PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkOpenIGTLinkTrackerTest.cxx
Go to the documentation of this file.
1 /*=Plus=header=begin======================================================
2  Program: Plus
3  Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved.
4  See License.txt for details.
5 =========================================================Plus=header=end*/
6 
7 // Local includes
8 #include "PlusConfigure.h"
9 #include "vtkPlusDataCollector.h"
10 #include "vtkPlusDataSource.h"
13 
14 // VTK includes
15 #include <vtkCallbackCommand.h>
16 #include <vtkSmartPointer.h>
17 #include <vtksys/CommandLineArguments.hxx>
18 
19 // STL includes
20 // TODO: uncomment the lines below when VS2010 is dropped:
21 //#include <chrono>
22 //#include <thread>
23 
24 vtkNew<vtkPlusOpenIGTLinkServer> server;
25 
26 void PrintLogsCallback(vtkObject* obj, unsigned long eid, void* clientdata, void* calldata);
27 
28 PlusStatus StartServer(vtkXMLDataElement* configRootElement, const std::string& configFilePath)
29 {
30  LOG_INFO("Server status: Reading configuration.");
31  // Create data collector instance
32  vtkSmartPointer<vtkPlusDataCollector> dataCollector = vtkSmartPointer<vtkPlusDataCollector>::New();
33  if (dataCollector->ReadConfiguration(configRootElement) != PLUS_SUCCESS)
34  {
35  LOG_ERROR("Datacollector failed to read configuration");
36  return PLUS_FAIL;
37  }
38 
39  // Create transform repository instance
40  vtkSmartPointer<vtkIGSIOTransformRepository> transformRepository = vtkSmartPointer<vtkIGSIOTransformRepository>::New();
41  if (transformRepository->ReadConfiguration(configRootElement) != PLUS_SUCCESS)
42  {
43  LOG_ERROR("Transform repository failed to read configuration");
44  return PLUS_FAIL;
45  }
46 
47  LOG_INFO("Server status: Connecting to devices.");
48  if (dataCollector->Connect() != PLUS_SUCCESS)
49  {
50  LOG_ERROR("Datacollector failed to connect to devices");
51  return PLUS_FAIL;
52  }
53 
54  if (dataCollector->Start() != PLUS_SUCCESS)
55  {
56  LOG_ERROR("Datacollector failed to start");
57  return PLUS_FAIL;
58  }
59 
60  XML_FIND_NESTED_ELEMENT_REQUIRED(serverElement, configRootElement, "PlusOpenIGTLinkServer");
61 
62  LOG_DEBUG("Initializing Plus OpenIGTLink server... ");
63  if (server->Start(dataCollector, transformRepository, serverElement, configFilePath) != PLUS_SUCCESS)
64  {
65  return PLUS_FAIL;
66  }
67 
68  return PLUS_SUCCESS;
69 }
70 
71 int main(int argc, char** argv)
72 {
73  bool printHelp(false);
74  std::string clientConfigFileName;
75  std::string serverConfigFileName;
76  bool renderingOff(false);
77 
78  vtksys::CommandLineArguments args;
79  args.Initialize(argc, argv);
80 
81  int verboseLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED;
82 
83  args.AddArgument("--help", vtksys::CommandLineArguments::NO_ARGUMENT, &printHelp, "Print this help.");
84  args.AddArgument("--client-config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &clientConfigFileName, "Config file containing the client configuration.");
85  args.AddArgument("--server-config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &serverConfigFileName, "Config file containing the server configuration.");
86  args.AddArgument("--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel, "Verbose level (1=error only, 2=warning, 3=info, 4=debug, 5=trace)");
87 
88  if (!args.Parse())
89  {
90  std::cerr << "Problem parsing arguments" << std::endl;
91  std::cout << "\n\nvtkPlusOpenIGTLinkTrackerTest help:" << args.GetHelp() << std::endl;
92  exit(EXIT_FAILURE);
93  }
94 
95  vtkPlusLogger::Instance()->SetLogLevel(verboseLevel);
96 
97  if (printHelp)
98  {
99  std::cout << "\n\nvtkPlusOpenIGTLinkTrackerTest help:" << args.GetHelp() << std::endl;
100  exit(EXIT_SUCCESS);
101  }
102 
103  // Read server config file
104  LOG_INFO("Reading server config file...");
105  vtkNew<vtkXMLDataElement> serverConfigRootElement;
106  if (PlusXmlUtils::ReadDeviceSetConfigurationFromFile(serverConfigRootElement, serverConfigFileName.c_str()) == PLUS_FAIL)
107  {
108  LOG_ERROR("Unable to read configuration from file " << serverConfigFileName.c_str());
109  return EXIT_FAILURE;
110  }
111 
112  if (StartServer(serverConfigRootElement, serverConfigFileName) != PLUS_SUCCESS)
113  {
114  LOG_ERROR("Unable to start server");
115  return EXIT_FAILURE;
116  }
117 
118  // Read client config file
119  LOG_INFO("Reading client config file...");
120  vtkNew<vtkXMLDataElement> clientConfigRootElement;
121  if (PlusXmlUtils::ReadDeviceSetConfigurationFromFile(clientConfigRootElement, clientConfigFileName.c_str()) == PLUS_FAIL)
122  {
123  LOG_ERROR("Unable to read configuration from file " << clientConfigFileName.c_str());
124  return EXIT_FAILURE;
125  }
126  vtkNew<vtkPlusOpenIGTLinkTracker> client;
127 
128  // Add an observer to warning and error events for redirecting it to the stdout
129  vtkNew<vtkCallbackCommand> callbackCommand;
130  callbackCommand->SetCallback(PrintLogsCallback);
131  client->AddObserver("WarningEvent", callbackCommand);
132  client->AddObserver("ErrorEvent", callbackCommand);
133  client->SetDeviceId("TrackerDevice");
134  if (client->ReadConfiguration(clientConfigRootElement) != PLUS_SUCCESS)
135  {
136  LOG_ERROR("Unable to configure client.");
137  return EXIT_FAILURE;
138  }
139 
140  LOG_INFO("Connect client...");
141  if (client->Connect() != PLUS_SUCCESS)
142  {
143  LOG_ERROR("Unable to connect client to server.");
144  return EXIT_FAILURE;
145  }
146 
147  if (client->StartRecording() != PLUS_SUCCESS)
148  {
149  LOG_ERROR("Unable to start recording of client device.");
150  return EXIT_FAILURE;
151  }
152 
153  // TODO: use the line below when VS2010 is dropped:
154  // std::this_thread::sleep_for(std::chrono::milliseconds(2000));
155  #ifdef _WIN32
156  Sleep(2000);
157  #else
158  usleep(2000000);
159  #endif
160 
161  auto channel = *client->GetOutputChannelsStart();
162  if (channel == nullptr)
163  {
164  LOG_ERROR("No channel configured for device.");
165  exit(EXIT_FAILURE);
166  }
167 
168  igsioTrackedFrame frame;
169  if (channel->GetTrackedFrame(frame) != PLUS_SUCCESS)
170  {
171  LOG_ERROR("Unable to retrieve frame from device.");
172  exit(EXIT_FAILURE);
173  }
174 
175  client->Disconnect();
176  LOG_INFO("Exit successfully");
177  exit(EXIT_SUCCESS);
178 }
179 
180 // Callback function for error and warning redirects
181 void PrintLogsCallback(vtkObject* obj, unsigned long eid, void* clientdata, void* calldata)
182 {
183  if (eid == vtkCommand::GetEventIdFromString("WarningEvent"))
184  {
185  LOG_WARNING((const char*)calldata);
186  }
187  else if (eid == vtkCommand::GetEventIdFromString("ErrorEvent"))
188  {
189  LOG_ERROR((const char*)calldata);
190  }
191 }
int * channel
Definition: phidget22.h:1303
igsioStatus PlusStatus
Definition: PlusCommon.h:40
void PrintLogsCallback(vtkObject *obj, unsigned long eid, void *clientdata, void *calldata)
#define PLUS_FAIL
Definition: PlusCommon.h:43
PlusStatus StartServer(vtkXMLDataElement *configRootElement, const std::string &configFilePath)
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
int main(int argc, char **argv)
static vtkIGSIOLogger * Instance()
static PlusStatus ReadDeviceSetConfigurationFromFile(vtkXMLDataElement *config, const char *filename)
Definition: PlusXmlUtils.h:23
vtkNew< vtkPlusOpenIGTLinkServer > server