Skip to content

Commit 30d01b8

Browse files
authored
ENH: Added network configuration for Atracsys and other improvements (#1269)
1 parent 0c75fc0 commit 30d01b8

5 files changed

Lines changed: 152 additions & 30 deletions

File tree

src/PlusDataCollection/Atracsys/AtracsysMarkerCreator.cxx

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,12 +479,13 @@ void TransformMarkerCoordinateSystem(Fiducials& fids)
479479
// Look for the largest *unique* distance from the centroid, the corresponding fiducial will
480480
// define the x-axis.
481481
vec3 x;
482+
int xfidId{ -1 };
482483
for (auto prev = dists.begin(), curr = ++dists.begin(); curr != dists.end(); ++prev, ++curr)
483484
{
484485
if (std::abs(prev->first - curr->first) > 0.1)
485486
{
486-
auto fidId = (prev == dists.begin()) ? prev->second : curr->second;
487-
x = vec3(fids[fidId]);
487+
xfidId = (prev == dists.begin()) ? prev->second : curr->second;
488+
x = vec3(fids[xfidId]);
488489
break;
489490
}
490491
}
@@ -497,12 +498,13 @@ void TransformMarkerCoordinateSystem(Fiducials& fids)
497498
}
498499
// Look for the largest *unique* distance from x-axis, it will define the plane of the y-axis.
499500
vec3 p;
501+
int yfidId{ -1 };
500502
for (auto prev = dists2.begin(), curr = ++dists2.begin(); curr != dists2.end(); ++prev, ++curr)
501503
{
502504
if (std::abs(prev->first - curr->first) > 0.1)
503505
{
504-
auto fidId = (prev == dists2.begin()) ? prev->second : curr->second;
505-
p = vec3(fids[fidId]);
506+
yfidId = (prev == dists2.begin()) ? prev->second : curr->second;
507+
p = vec3(fids[yfidId]);
506508
break;
507509
}
508510
}
@@ -511,6 +513,24 @@ void TransformMarkerCoordinateSystem(Fiducials& fids)
511513
vec3 vz = (vx.cross(p - c)).normalize();
512514
vec3 vy = vz.cross(vx);
513515

516+
// Create new fiducial order:
517+
// {fiducial defining x-axis, fiducial defining y-axis, remaining fiducials in descending order
518+
// of distance to x-axis}
519+
std::vector<int> newFidOrder{ xfidId, yfidId };
520+
for (auto d = dists2.begin(); d != dists2.end(); ++d)
521+
{
522+
if (d->second != xfidId && d->second != yfidId)
523+
newFidOrder.push_back(d->second);
524+
}
525+
// Apply new order to fiducials
526+
for (int i = 0; i < newFidOrder.size(); ++i) {
527+
size_t j = newFidOrder[i];
528+
while (j != i) {
529+
std::swap(fids[i], fids[j]);
530+
std::swap(newFidOrder[i], newFidOrder[j]);
531+
j = newFidOrder[i];
532+
}
533+
}
514534
// Store the coordinates of each fiducial in the new coordinate system.
515535
for (auto& fid : fids)
516536
{

src/PlusDataCollection/Atracsys/AtracsysTracker.cxx

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ class Tracker::Internal
374374
// library version
375375
std::string LibVersion;
376376

377+
// firmware soft version
378+
std::string FirmwareSoftwareVersion;
379+
377380
// calibration date
378381
std::string CalibrationDate;
379382

@@ -682,7 +685,7 @@ bool Tracker::IsVirtual()
682685
}
683686

684687
//----------------------------------------------------------------------------
685-
Tracker::RESULT Tracker::Connect()
688+
Tracker::RESULT Tracker::Connect(const std::string& networkConfigFile)
686689
{
687690
if (this->InternalObj->FtkLib != nullptr && this->InternalObj->TrackerSN != 0)
688691
{
@@ -691,11 +694,24 @@ Tracker::RESULT Tracker::Connect()
691694
}
692695

693696
// initialize SDK
694-
this->InternalObj->FtkLib = ftkInit();
695-
696-
if (this->InternalObj->FtkLib == NULL)
697+
if (networkConfigFile.empty())
697698
{
698-
return ERROR_UNABLE_TO_GET_FTK_HANDLE;
699+
this->InternalObj->FtkLib = ftkInit();
700+
if (this->InternalObj->FtkLib == NULL)
701+
{
702+
return ERROR_UNABLE_TO_GET_FTK_HANDLE;
703+
}
704+
}
705+
else
706+
{
707+
ftkBuffer buffer;
708+
this->InternalObj->FtkLib = ftkInitExt(networkConfigFile.c_str(), &buffer);
709+
if (this->InternalObj->FtkLib == NULL)
710+
{
711+
LOG_ERROR(buffer.data);
712+
LOG_ERROR("Cannot initialize library with the provided network configuration.");
713+
return ERROR_UNABLE_TO_GET_FTK_HANDLE;
714+
}
699715
}
700716

701717
DeviceData device;
@@ -779,6 +795,14 @@ Tracker::RESULT Tracker::Connect()
779795
ftkGetData(this->InternalObj->FtkLib, this->InternalObj->TrackerSN, info->id, &buff);
780796
this->InternalObj->CalibrationDate = std::string(buff.data);
781797

798+
if (!this->GetOptionInfo("Device software version", info))
799+
{
800+
LOG_ERROR("Option unknown: \"Device software version\"");
801+
return ERROR_OPTION_NOT_FOUND;
802+
}
803+
ftkGetData(this->InternalObj->FtkLib, this->InternalObj->TrackerSN, info->id, &buff);
804+
this->InternalObj->FirmwareSoftwareVersion = std::string(buff.data);
805+
782806
// Check whether onboard processing is off or on (spryTrack only)
783807
if (this->DeviceType == SPRYTRACK_180 || this->DeviceType == SPRYTRACK_300)
784808
{
@@ -831,6 +855,13 @@ Tracker::RESULT Tracker::GetSDKversion(std::string& version)
831855
return SUCCESS;
832856
}
833857

858+
//----------------------------------------------------------------------------
859+
Tracker::RESULT Tracker::GetFirmwareSoftwareVersion(std::string& version)
860+
{
861+
version = this->InternalObj->FirmwareSoftwareVersion;
862+
return SUCCESS;
863+
}
864+
834865
//----------------------------------------------------------------------------
835866
Tracker::RESULT Tracker::GetCalibrationDate(std::string& date)
836867
{
@@ -954,6 +985,16 @@ Tracker::RESULT Tracker::GetLoadedGeometries(std::map<int, std::vector<std::arra
954985
return SUCCESS;
955986
}
956987

988+
//----------------------------------------------------------------------------
989+
Tracker::RESULT Tracker::GetFiducialCoordinates(int geomId, std::vector<std::array<float, 3>>& fidCoords)
990+
{
991+
if (this->InternalObj->Geometries.find(geomId) == this->InternalObj->Geometries.cend())
992+
return ERROR_REQUESTED_GEOMETRY_NOT_FOUND;
993+
994+
fidCoords = this->InternalObj->Geometries.at(geomId);
995+
return SUCCESS;
996+
}
997+
957998
//----------------------------------------------------------------------------
958999
std::string Tracker::ResultToString(Tracker::RESULT result)
9591000
{

src/PlusDataCollection/Atracsys/AtracsysTracker.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ namespace Atracsys
125125
ERROR_CANNOT_GET_MARKER_INFO,
126126
ERROR_FAILED_TO_SET_STK_PROCESSING_TYPE,
127127
ERROR_OPTION_NOT_FOUND,
128-
ERROR_SET_OPTION
128+
ERROR_SET_OPTION,
129+
ERROR_REQUESTED_GEOMETRY_NOT_FOUND
129130
};
130131

131132
enum DEVICE_TYPE
@@ -153,14 +154,17 @@ namespace Atracsys
153154
void Pause(bool tof);
154155

155156
/*! Connect to Atracsys tracker, must be called before any other function in this wrapper API. */
156-
RESULT Connect();
157+
RESULT Connect(const std::string& networkConfigFile = "");
157158

158159
/*! Closes connections to Atracsys tracker, must be called at end of application. */
159160
RESULT Disconnect();
160161

161162
/*! */
162163
RESULT GetSDKversion(std::string& version);
163164

165+
/*! */
166+
RESULT GetFirmwareSoftwareVersion(std::string& version);
167+
164168
/*! */
165169
RESULT GetCalibrationDate(std::string& date);
166170

@@ -191,6 +195,9 @@ namespace Atracsys
191195
/*! */
192196
RESULT GetLoadedGeometries(std::map<int, std::vector<std::array<float,3>>>& geometries);
193197

198+
/*! */
199+
RESULT GetFiducialCoordinates(int geomId, std::vector<std::array<float, 3>>& fidCoords);
200+
194201
/*! */
195202
std::string ResultToString(RESULT result);
196203

src/PlusDataCollection/Atracsys/vtkPlusAtracsysTracker.cxx

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,12 @@ class vtkPlusAtracsysTracker::vtkInternal
8484
int MaxMissingFiducials = 0; // maximum number of missing fiducials
8585

8686
// matches plus tool id to .ini geometry file names/paths
87-
std::map<std::string, std::string> PlusIdMappedToGeometryFilename;
87+
std::map<std::string, std::string> ToolIdMappedToGeometryFilename;
8888

89-
// matches fusionTrack internal tool geometry ID to Plus tool ID for updating tools
90-
std::map<int, std::string> FtkGeometryIdMappedToToolId;
89+
// matches Atracsys internal tool geometry ID to Plus tool ID for updating tools
90+
std::map<int, std::string> AtracGeomIdMappedToToolId;
91+
// reverse lookup, Plus tool ID to Atracsys internal tool geometry ID
92+
std::map<std::string, int> ToolIdMappedToAtracGeomId;
9193

9294
// Atracsys API wrapper class handle
9395
Atracsys::Tracker Tracker;
@@ -130,6 +132,14 @@ std::string vtkPlusAtracsysTracker::GetSdkVersion()
130132
return v;
131133
}
132134

135+
//----------------------------------------------------------------------------
136+
std::string vtkPlusAtracsysTracker::GetFirmwareSoftwareVersion()
137+
{
138+
std::string d;
139+
this->InternalObj->Tracker.GetFirmwareSoftwareVersion(d);
140+
return d;
141+
}
142+
133143
//----------------------------------------------------------------------------
134144
std::string vtkPlusAtracsysTracker::GetCalibrationDate()
135145
{
@@ -187,6 +197,32 @@ PlusStatus vtkPlusAtracsysTracker::GetLoadedGeometries(std::map<int, std::vector
187197
return PLUS_SUCCESS;
188198
}
189199

200+
//----------------------------------------------------------------------------
201+
PlusStatus vtkPlusAtracsysTracker::GetMarkerGeometry(std::string toolId, std::string& relPath,
202+
int& geomId, std::vector<std::array<float, 3>>& fidCoords)
203+
{
204+
if (this->InternalObj->ToolIdMappedToGeometryFilename.find(toolId) == this->InternalObj->ToolIdMappedToGeometryFilename.cend())
205+
{
206+
LOG_ERROR("Could not get geometry filename for tool " << toolId);
207+
return PLUS_FAIL;
208+
}
209+
relPath = this->InternalObj->ToolIdMappedToGeometryFilename.at(toolId);
210+
211+
if (this->InternalObj->ToolIdMappedToAtracGeomId.find(toolId) == this->InternalObj->ToolIdMappedToAtracGeomId.cend())
212+
{
213+
LOG_ERROR("Could not get marker geometry for tool " << toolId);
214+
return PLUS_FAIL;
215+
}
216+
geomId = this->InternalObj->ToolIdMappedToAtracGeomId.at(toolId);
217+
218+
if (this->InternalObj->Tracker.GetFiducialCoordinates(geomId, fidCoords) != ATR_SUCCESS)
219+
{
220+
LOG_ERROR("Could not get fiducial coordinates for geometry id " << geomId);
221+
return PLUS_FAIL;
222+
}
223+
return PLUS_SUCCESS;
224+
}
225+
190226
//----------------------------------------------------------------------------
191227
bool vtkPlusAtracsysTracker::IsVirtual() const
192228
{
@@ -238,13 +274,13 @@ PlusStatus vtkPlusAtracsysTracker::ReadConfiguration(vtkXMLDataElement* rootConf
238274
XML_READ_ENUM2_ATTRIBUTE_NONMEMBER_OPTIONAL(TrackingType, toolTrackingType, toolDataElement, "ACTIVE", ACTIVE, "PASSIVE", PASSIVE);
239275
if (toolTrackingType == ACTIVE)
240276
{
241-
// active tool, can be loaded directly into FtkGeometryIdMappedToToolId
277+
// active tool, can be loaded directly into AtracGeomIdMappedToToolId
242278
int ftkGeometryId = -1;
243279
XML_READ_SCALAR_ATTRIBUTE_NONMEMBER_OPTIONAL(int, GeometryId, ftkGeometryId, toolDataElement);
244280
if (ftkGeometryId != -1)
245281
{
246-
std::pair<int, std::string> thisTool(ftkGeometryId, toolId);
247-
this->InternalObj->FtkGeometryIdMappedToToolId.insert(thisTool);
282+
this->InternalObj->AtracGeomIdMappedToToolId.insert(std::make_pair(ftkGeometryId, toolId));
283+
this->InternalObj->ToolIdMappedToAtracGeomId.insert(std::make_pair(toolId, ftkGeometryId));
248284
}
249285
else
250286
{
@@ -254,12 +290,11 @@ PlusStatus vtkPlusAtracsysTracker::ReadConfiguration(vtkXMLDataElement* rootConf
254290
}
255291
else if (toolTrackingType == PASSIVE)
256292
{
257-
// passive tool, load into PlusIdMappedToGeometryFilename to have geometry loaded in InternalConnect
293+
// passive tool, load into ToolIdMappedToGeometryFilename to have geometry loaded in InternalConnect
258294
const char* geometryFile;
259295
if ((geometryFile = toolDataElement->GetAttribute("GeometryFile")) != NULL)
260296
{
261-
std::pair<std::string, std::string> thisTool(toolId, geometryFile);
262-
this->InternalObj->PlusIdMappedToGeometryFilename.insert(thisTool);
297+
this->InternalObj->ToolIdMappedToGeometryFilename.insert(std::make_pair(toolId, geometryFile));
263298
}
264299
else
265300
{
@@ -326,8 +361,17 @@ PlusStatus vtkPlusAtracsysTracker::InternalConnect()
326361
{
327362
LOG_TRACE("vtkPlusAtracsysTracker::InternalConnect");
328363

364+
// Check if network configuration file is provided
365+
std::string networkConfigPath;
366+
if (this->InternalObj->DeviceOptions.find("NetworkConfigFile") != this->InternalObj->DeviceOptions.end())
367+
{
368+
networkConfigPath = vtkPlusConfig::GetInstance()->GetDeviceSetConfigurationPath(
369+
this->InternalObj->DeviceOptions["NetworkConfigFile"]);
370+
}
371+
329372
// Connect to device
330-
ATR_RESULT result = this->InternalObj->Tracker.Connect();
373+
ATR_RESULT result = this->InternalObj->Tracker.Connect(networkConfigPath.empty() ? "" : networkConfigPath.c_str());
374+
331375
if (result != ATR_SUCCESS && result != ATR_RESULT::WARNING_CONNECTED_IN_USB2)
332376
{
333377
LOG_ERROR(this->InternalObj->Tracker.ResultToString(result));
@@ -540,7 +584,8 @@ PlusStatus vtkPlusAtracsysTracker::InternalConnect()
540584
}
541585
}
542586
else if (itr->first != "AcquisitionRate" && itr->first != "Id" && itr->first != "Type"
543-
&& itr->first != "ToolReferenceFrame" && itr->first != "Enable_embedded_processing")
587+
&& itr->first != "ToolReferenceFrame" && itr->first != "Enable_embedded_processing"
588+
&& itr->first != "NetworkConfigFile")
544589
{
545590
LOG_WARNING("Unknown option \"" << itr->first << "\".");
546591
itr = this->InternalObj->DeviceOptions.erase(itr);
@@ -564,7 +609,7 @@ PlusStatus vtkPlusAtracsysTracker::InternalConnect()
564609

565610
// load passive geometries onto Atracsys
566611
std::map<std::string, std::string>::iterator it;
567-
for (it = begin(this->InternalObj->PlusIdMappedToGeometryFilename); it != end(this->InternalObj->PlusIdMappedToGeometryFilename); it++)
612+
for (it = begin(this->InternalObj->ToolIdMappedToGeometryFilename); it != end(this->InternalObj->ToolIdMappedToGeometryFilename); it++)
568613
{
569614
// load user defined geometry file
570615
// TODO: add check for conflicting marker IDs
@@ -575,8 +620,8 @@ PlusStatus vtkPlusAtracsysTracker::InternalConnect()
575620
LOG_ERROR(this->InternalObj->Tracker.ResultToString(result) << " This error occurred when trying to load geometry file at path: " << geomFilePath);
576621
return PLUS_FAIL;
577622
}
578-
std::pair<int, std::string> newTool(geometryId, it->first);
579-
this->InternalObj->FtkGeometryIdMappedToToolId.insert(newTool);
623+
this->InternalObj->AtracGeomIdMappedToToolId.insert(std::make_pair(geometryId, it->first));
624+
this->InternalObj->ToolIdMappedToAtracGeomId.insert(std::make_pair(it->first, geometryId));
580625
}
581626

582627
// if active marker pairing is desired, then its time > 0 second
@@ -702,7 +747,7 @@ PlusStatus vtkPlusAtracsysTracker::InternalUpdate()
702747
}
703748

704749
std::map<int, std::string>::iterator it;
705-
for (it = this->InternalObj->FtkGeometryIdMappedToToolId.begin(); it != this->InternalObj->FtkGeometryIdMappedToToolId.end(); it++)
750+
for (it = this->InternalObj->AtracGeomIdMappedToToolId.begin(); it != this->InternalObj->AtracGeomIdMappedToToolId.end(); it++)
706751
{
707752
if (std::find(this->DisabledToolIds.begin(), this->DisabledToolIds.end(), it->second) != this->DisabledToolIds.end())
708753
{
@@ -834,7 +879,7 @@ PlusStatus vtkPlusAtracsysTracker::SetToolEnabled(std::string toolId, bool enabl
834879
// tool should be disabled, if it exists add to disabled list
835880
bool toolExists = false;
836881
std::map<int, std::string>::iterator it;
837-
for (it = this->InternalObj->FtkGeometryIdMappedToToolId.begin(); it != this->InternalObj->FtkGeometryIdMappedToToolId.end(); it++)
882+
for (it = this->InternalObj->AtracGeomIdMappedToToolId.begin(); it != this->InternalObj->AtracGeomIdMappedToToolId.end(); it++)
838883
{
839884
if (igsioCommon::IsEqualInsensitive(it->second, toolId))
840885
{
@@ -859,7 +904,7 @@ PlusStatus vtkPlusAtracsysTracker::AddToolGeometry(std::string toolId, std::stri
859904
// make sure geometry with toolId doesn't already exist
860905
bool toolExists = false;
861906
std::map<int, std::string>::iterator it;
862-
for (it = this->InternalObj->FtkGeometryIdMappedToToolId.begin(); it != this->InternalObj->FtkGeometryIdMappedToToolId.end(); it++)
907+
for (it = this->InternalObj->AtracGeomIdMappedToToolId.begin(); it != this->InternalObj->AtracGeomIdMappedToToolId.end(); it++)
863908
{
864909
if (igsioCommon::IsEqualInsensitive(it->second, toolId))
865910
{
@@ -889,7 +934,7 @@ PlusStatus vtkPlusAtracsysTracker::AddToolGeometry(std::string toolId, std::stri
889934
aToolSource->SetId(toolId);
890935
this->AddTool(aToolSource);
891936

892-
// TO DO: add fiducial data as separate sources ?
937+
// TODO: add fiducial data as separate sources ?
893938
//vtkSmartPointer<vtkPlusDataSource> aFids3dSource = vtkSmartPointer<vtkPlusDataSource>::New();
894939
//aFids3dSource->SetReferenceCoordinateFrameName(this->ToolReferenceFrameName);
895940
//aFids3dSource->SetType(DATA_SOURCE_TYPE_FIELDDATA);
@@ -925,7 +970,7 @@ PlusStatus vtkPlusAtracsysTracker::AddToolGeometry(std::string toolId, std::stri
925970

926971
// register this tool internally
927972
std::pair<int, std::string> newTool(geometryId, toolId);
928-
this->InternalObj->FtkGeometryIdMappedToToolId.insert(newTool);
973+
this->InternalObj->AtracGeomIdMappedToToolId.insert(newTool);
929974

930975
return PLUS_SUCCESS;
931976
}

0 commit comments

Comments
 (0)