Skip to content

Commit

Permalink
Adding tooltips to the visualizer so you can see which markers are which
Browse files Browse the repository at this point in the history
  • Loading branch information
keenon committed Jun 27, 2022
1 parent 86fc5ac commit 65cf969
Show file tree
Hide file tree
Showing 21 changed files with 1,249 additions and 82 deletions.
2 changes: 1 addition & 1 deletion VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.8.3
0.8.4
215 changes: 215 additions & 0 deletions dart/biomechanics/MarkerFitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,41 @@ MarkersErrorReport MarkerFitter::generateDataErrorsReport(
}
}

// 2. Generate a warning if there aren't enough fixed markers on the pelvis
bool hasPelvis = false;
for (int i = 0; i < mSkeleton->getNumBodyNodes(); i++)
{
std::string name = mSkeleton->getBodyNode(i)->getName();
if (name == "pelvis" || name == "Pelvis" || name == "PELVIS")
{
hasPelvis = true;
break;
}
}
if (hasPelvis)
{
int numFixedOnPelvis = 0;
for (int i = 0; i < mMarkerNames.size(); i++)
{
if (mMarkers[i].first->getName() == "pelvis"
|| mMarkers[i].first->getName() == "Pelvis"
|| mMarkers[i].first->getName() == "PELVIS")
{
if (!mMarkerIsTracking[i] && observedMarkersMap.count(mMarkerNames[i]))
{
numFixedOnPelvis++;
}
}
}
if (numFixedOnPelvis < 3)
{
report.warnings.push_back(
"Need more fixed markers on the pelvis! This trial only has "
+ std::to_string(numFixedOnPelvis)
+ ". We recommend 3 (or more) for good results.");
}
}

// 3. Generate a warning about mismatched markers between the model and the
// data.

Expand Down Expand Up @@ -1491,6 +1526,11 @@ void MarkerFitter::debugTrajectoryAndMarkersToGUI(
std::string anatomicalMarkersLayerName = "Anatomical Markers";
Eigen::Vector4s anatomicalMarkersLayerColor
= Eigen::Vector4s(0.0, 0.0, 1.0, 1.0);
std::string unusedMarkersLayerName = "Unused Markers";
Eigen::Vector4s unusedMarkersLayerColor = Eigen::Vector4s(1.0, 0.5, 0.5, 1.0);
std::string virtualMarkersLayerName = "Virtual Markers";
Eigen::Vector4s virtualMarkersLayerColor
= Eigen::Vector4s(0.5, 1.0, 0.5, 1.0);
std::string markersErrorLayerName = "Marker Errors";
Eigen::Vector4s markersErrorLayerColor = Eigen::Vector4s(1.0, 0.0, 0.0, 1.0);
std::string forcePlateLayerName = "Force Plates";
Expand All @@ -1512,6 +1552,8 @@ void MarkerFitter::debugTrajectoryAndMarkersToGUI(
trackingMarkersLayerName, trackingMarkersLayerColor, true);
server->createLayer(
anatomicalMarkersLayerName, anatomicalMarkersLayerColor, true);
server->createLayer(unusedMarkersLayerName, unusedMarkersLayerColor, true);
server->createLayer(virtualMarkersLayerName, virtualMarkersLayerColor, false);
server->createLayer(markersErrorLayerName, markersErrorLayerColor, true);
server->createLayer(forcePlateLayerName, forcePlateLayerColor, true);

Expand All @@ -1538,6 +1580,9 @@ void MarkerFitter::debugTrajectoryAndMarkersToGUI(
{
if (init.jointWeights(i) > 0)
{
server->setObjectTooltip(
"joint_center_" + std::to_string(i),
"Joint center: " + init.joints[i]->getName());
server->createSphere(
"joint_center_" + std::to_string(i),
0.01 * std::min(3.0, (1.0 / init.jointWeights(i))),
Expand Down Expand Up @@ -1590,6 +1635,42 @@ void MarkerFitter::debugTrajectoryAndMarkersToGUI(
}
}

std::set<std::string> observedMarkers;
for (int i = 0; i < markerObservations.size(); i++)
{
for (auto pair : markerObservations[i])
{
observedMarkers.emplace(pair.first);
}
}

for (std::string marker : observedMarkers)
{
if (mMarkerMap.count(marker) == 0)
{
server->setObjectTooltip(
"marker_unused_" + marker, "Unused Marker: " + marker);
}
}

for (int i = 0; i < mMarkerNames.size(); i++)
{
if (observedMarkers.count(mMarkerNames[i]) == 0)
{
server->setObjectTooltip(
"marker_virtual_" + mMarkerNames[i],
"Virtual Marker: " + mMarkerNames[i]);
}
else
{
bool isTracking = mMarkerIsTracking[i];
server->setObjectTooltip(
"marker_real_" + mMarkerNames[i],
(isTracking ? "Tracking Marker: " : "Anatomical Marker: ")
+ mMarkerNames[i]);
}
}

s_t secondsPerTick = 1.0 / 50;
std::shared_ptr<realtime::Ticker> ticker
= std::make_shared<realtime::Ticker>(secondsPerTick);
Expand All @@ -1609,6 +1690,11 @@ void MarkerFitter::debugTrajectoryAndMarkersToGUI(
trackingMarkersLayerColor,
anatomicalMarkersLayerName,
anatomicalMarkersLayerColor,
unusedMarkersLayerName,
unusedMarkersLayerColor,
virtualMarkersLayerName,
virtualMarkersLayerColor,
observedMarkers,
markersErrorLayerColor,
markersErrorLayerName,
originalMarkerLocationsLayerName,
Expand Down Expand Up @@ -1693,6 +1779,44 @@ void MarkerFitter::debugTrajectoryAndMarkersToGUI(
originalMarkerLocationsLayerName);
}
}
else
{
server->createBox(
"marker_unused_" + pair.first,
Eigen::Vector3s::Ones() * 0.01,
pair.second,
Eigen::Vector3s::Zero(),
unusedMarkersLayerColor,
unusedMarkersLayerName);
}
}

std::map<std::string, Eigen::Vector3s> markerWorldPosition
= mSkeleton->getMarkerMapWorldPositions(mMarkerMap);
for (auto pair : markerWorldPosition)
{
if (markerWorldPositions.count(pair.first) == 0)
{
if (init.updatedMarkerMap.count(pair.first) > 0)
{
server->deleteObject("marker_original_" + pair.first);
}
else
{
server->deleteObject("marker_unused_" + pair.first);
}
}
if (observedMarkers.count(pair.first) == 0)
{
// This is a virtual marker:
server->createBox(
"marker_virtual_" + pair.first,
Eigen::Vector3s::Ones() * 0.01,
pair.second,
Eigen::Vector3s::Zero(),
virtualMarkersLayerColor,
virtualMarkersLayerName);
}
}

if (goldOsim && goldPoses.size() > 0)
Expand Down Expand Up @@ -1787,6 +1911,13 @@ void MarkerFitter::debugTrajectoryAndMarkersToGUI(
}
});
server->registerConnectionListener([ticker]() { ticker->start(); });

server->registerKeydownListener([ticker](std::string key) {
if (key == " ")
{
ticker->toggle();
}
});
// TODO: it'd be nice if this method didn't block forever, but we need to hold
// onto a bunch of resources otherwise
// server->blockWhileServing();
Expand All @@ -1811,6 +1942,11 @@ void MarkerFitter::saveTrajectoryAndMarkersToGUI(
std::string anatomicalMarkersLayerName = "Anatomical Markers";
Eigen::Vector4s anatomicalMarkersLayerColor
= Eigen::Vector4s(0.0, 0.0, 1.0, 1.0);
std::string unusedMarkersLayerName = "Unused Markers";
Eigen::Vector4s unusedMarkersLayerColor = Eigen::Vector4s(1.0, 0.5, 0.5, 1.0);
std::string virtualMarkersLayerName = "Virtual Markers";
Eigen::Vector4s virtualMarkersLayerColor
= Eigen::Vector4s(0.5, 1.0, 0.5, 1.0);
std::string markersErrorLayerName = "Marker Errors";
Eigen::Vector4s markersErrorLayerColor = Eigen::Vector4s(1.0, 0.0, 0.0, 1.0);
std::string forcePlateLayerName = "Force Plates";
Expand All @@ -1833,6 +1969,8 @@ void MarkerFitter::saveTrajectoryAndMarkersToGUI(
server.createLayer(trackingMarkersLayerName, trackingMarkersLayerColor, true);
server.createLayer(
anatomicalMarkersLayerName, anatomicalMarkersLayerColor, true);
server.createLayer(unusedMarkersLayerName, unusedMarkersLayerColor, true);
server.createLayer(virtualMarkersLayerName, virtualMarkersLayerColor, false);
server.createLayer(markersErrorLayerName, markersErrorLayerColor, true);
server.createLayer(forcePlateLayerName, forcePlateLayerColor, true);

Expand All @@ -1858,6 +1996,9 @@ void MarkerFitter::saveTrajectoryAndMarkersToGUI(
{
if (init.jointWeights(i) > 0)
{
server.setObjectTooltip(
"joint_center_" + std::to_string(i),
"Joint center: " + init.joints[i]->getName());
server.createSphere(
"joint_center_" + std::to_string(i),
0.01 * std::min(3.0, (1.0 / init.jointWeights(i))),
Expand Down Expand Up @@ -1910,6 +2051,42 @@ void MarkerFitter::saveTrajectoryAndMarkersToGUI(
}
}

std::set<std::string> observedMarkers;
for (int i = 0; i < markerObservations.size(); i++)
{
for (auto pair : markerObservations[i])
{
observedMarkers.emplace(pair.first);
}
}

for (std::string marker : observedMarkers)
{
if (mMarkerMap.count(marker) == 0)
{
server.setObjectTooltip(
"marker_unused_" + marker, "Unused Marker: " + marker);
}
}

for (int i = 0; i < mMarkerNames.size(); i++)
{
if (observedMarkers.count(mMarkerNames[i]) == 0)
{
server.setObjectTooltip(
"marker_virtual_" + mMarkerNames[i],
"Virtual Marker: " + mMarkerNames[i]);
}
else
{
bool isTracking = mMarkerIsTracking[i];
server.setObjectTooltip(
"marker_real_" + mMarkerNames[i],
(isTracking ? "Tracking Marker: " : "Anatomical Marker: ")
+ mMarkerNames[i]);
}
}

for (int timestep = 0; timestep < init.poses.cols(); timestep++)
{
mSkeleton->setPositions(init.poses.col(timestep));
Expand Down Expand Up @@ -1985,6 +2162,44 @@ void MarkerFitter::saveTrajectoryAndMarkersToGUI(
originalMarkerLocationsLayerName);
}
}
else
{
server.createBox(
"marker_unused_" + pair.first,
Eigen::Vector3s::Ones() * 0.01,
pair.second,
Eigen::Vector3s::Zero(),
unusedMarkersLayerColor,
unusedMarkersLayerName);
}
}

std::map<std::string, Eigen::Vector3s> markerWorldPosition
= mSkeleton->getMarkerMapWorldPositions(mMarkerMap);
for (auto pair : markerWorldPosition)
{
if (markerWorldPositions.count(pair.first) == 0)
{
if (init.updatedMarkerMap.count(pair.first) > 0)
{
server.deleteObject("marker_original_" + pair.first);
}
else
{
server.deleteObject("marker_unused_" + pair.first);
}
}
if (observedMarkers.count(pair.first) == 0)
{
// This is a virtual marker:
server.createBox(
"marker_virtual_" + pair.first,
Eigen::Vector3s::Ones() * 0.01,
pair.second,
Eigen::Vector3s::Zero(),
virtualMarkersLayerColor,
virtualMarkersLayerName);
}
}

if (goldOsim && goldPoses.size() > 0)
Expand Down
11 changes: 11 additions & 0 deletions dart/proto/GUI.proto
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ message Command {
SetObjectRotation set_object_rotation = 6;
SetObjectColor set_object_color = 7;
SetObjectScale set_object_scale = 8;
SetObjectTooltip set_object_tooltip = 32;
DeleteObjectTooltip delete_object_tooltip = 33;
EnableMouseInteraction enable_mouse_interaction = 18;
CreateText text = 12;
CreateButton button = 13;
Expand Down Expand Up @@ -131,6 +133,15 @@ message SetObjectScale {
repeated float data = 2;
}

message SetObjectTooltip {
int32 key = 1;
string tooltip = 2;
}

message DeleteObjectTooltip {
int32 key = 1;
}

message EnableMouseInteraction {
int32 key = 1;
}
Expand Down
13 changes: 13 additions & 0 deletions dart/realtime/Ticker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ void Ticker::stop()
delete mMainThread;
}

void Ticker::toggle()
{
if (mRunning)
stop();
else
start();
}

bool Ticker::isRunning()
{
return mRunning;
}

void Ticker::mainLoop()
{
while (mRunning)
Expand Down
2 changes: 2 additions & 0 deletions dart/realtime/Ticker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class Ticker

void start();
void stop();
void toggle();
bool isRunning();

protected:
void mainLoop();
Expand Down
Loading

0 comments on commit 65cf969

Please sign in to comment.