12 #include "PlusConfigure.h" 13 #include "igtlCommon.h" 14 #include "igtlTrackingDataMessage.h" 15 #include "igtl_header.h" 26 #ifdef PLUS_USE_STEALTHLINK 29 #ifdef PLUS_USE_CLARIUS 34 #include "vtksys/CommandLineArguments.hxx" 35 #include "vtksys/Process.h" 36 #include "vtkXMLUtilities.h" 38 #include "igtlTransformMessage.h" 54 static vtkPlusOpenIGTLinkClientWithTransformLogging*
New();
59 bool messageBodyReceived =
false;
60 igtl::MessageBase::Pointer bodyMsg = this->IgtlMessageFactory->CreateReceiveMessage(messageHeader);
63 LOG_ERROR(
"Unable to create message of type: " << messageHeader->GetMessageType());
67 if (
typeid(*bodyMsg) ==
typeid(igtl::TransformMessage))
69 igtl::TransformMessage::Pointer transformMsg = dynamic_cast<igtl::TransformMessage*>(bodyMsg.GetPointer());
70 transformMsg->SetMessageHeader(messageHeader);
71 transformMsg->AllocatePack();
72 SocketReceive(transformMsg->GetBufferBodyPointer(), transformMsg->GetBufferBodySize());
73 messageBodyReceived =
true;
75 int c = transformMsg->Unpack(1);
76 if (!(c & igtl::MessageHeader::UNPACK_BODY))
78 LOG_ERROR(
"Failed to receive TRANSFORM reply (invalid body)");
79 return messageBodyReceived;
84 transformMsg->GetMatrix(mx);
85 LOG_INFO(
"Matrix for " << transformMsg->GetDeviceName() <<
" TRANSFORM received: ");
86 igtl::PrintMatrix(mx);
90 LOG_INFO(
"Received " << messageHeader->GetMessageType() <<
" message.");
93 return messageBodyReceived;
97 vtkPlusOpenIGTLinkClientWithTransformLogging() {};
98 virtual ~vtkPlusOpenIGTLinkClientWithTransformLogging() {};
100 vtkPlusOpenIGTLinkClientWithTransformLogging(
const vtkPlusOpenIGTLinkClientWithTransformLogging&);
101 void operator=(
const vtkPlusOpenIGTLinkClientWithTransformLogging&);
112 vtkSmartPointer<vtkXMLDataElement> cmdConfig = vtkSmartPointer<vtkXMLDataElement>::New();
114 std::ostringstream xmlStr;
115 vtkXMLUtilities::FlattenElement(cmdConfig, xmlStr);
117 LOG_INFO(
">>> Command: " << xmlStr.str());
123 vtkSmartPointer<vtkPlusStartStopRecordingCommand> cmd = vtkSmartPointer<vtkPlusStartStopRecordingCommand>::New();
124 cmd->SetNameToStart();
125 cmd->SetId(commandId);
126 cmd->SetOutputFilename(outputFilename.c_str());
127 cmd->SetEnableCompression(enableCompression);
128 if (!deviceId.empty())
130 cmd->SetCaptureDeviceId(deviceId.c_str());
139 vtkSmartPointer<vtkPlusStartStopRecordingCommand> cmd = vtkSmartPointer<vtkPlusStartStopRecordingCommand>::New();
140 cmd->SetNameToStop();
141 cmd->SetId(commandId);
142 cmd->SetOutputFilename(outputFilename.c_str());
143 if (!deviceId.empty())
145 cmd->SetCaptureDeviceId(deviceId.c_str());
154 vtkSmartPointer<vtkPlusStartStopRecordingCommand> cmd = vtkSmartPointer<vtkPlusStartStopRecordingCommand>::New();
155 cmd->SetNameToSuspend();
156 cmd->SetId(commandId);
157 if (!deviceId.empty())
159 cmd->SetCaptureDeviceId(deviceId.c_str());
168 vtkSmartPointer<vtkPlusStartStopRecordingCommand> cmd = vtkSmartPointer<vtkPlusStartStopRecordingCommand>::New();
169 cmd->SetNameToResume();
170 cmd->SetId(commandId);
171 if (!deviceId.empty())
173 cmd->SetCaptureDeviceId(deviceId.c_str());
181 const std::string& deviceId,
182 const std::string& inputFilename,
183 const std::string& outputFilename,
184 const std::string& outputImageName,
int commandId)
186 vtkSmartPointer<vtkPlusReconstructVolumeCommand> cmd = vtkSmartPointer<vtkPlusReconstructVolumeCommand>::New();
187 cmd->SetNameToReconstruct();
188 cmd->SetId(commandId);
189 if (!deviceId.empty())
191 cmd->SetVolumeReconstructorDeviceId(deviceId.c_str());
193 cmd->SetInputSeqFilename(inputFilename.c_str());
194 if (!outputFilename.empty())
196 cmd->SetOutputVolFilename(outputFilename.c_str());
198 if (!outputImageName.empty())
200 cmd->SetOutputVolDeviceName(outputImageName.c_str());
209 vtkSmartPointer<vtkPlusReconstructVolumeCommand> cmd = vtkSmartPointer<vtkPlusReconstructVolumeCommand>::New();
210 cmd->SetNameToStart();
211 cmd->SetId(commandId);
212 if (!deviceId.empty())
214 cmd->SetVolumeReconstructorDeviceId(deviceId.c_str());
223 vtkSmartPointer<vtkPlusReconstructVolumeCommand> cmd = vtkSmartPointer<vtkPlusReconstructVolumeCommand>::New();
224 cmd->SetNameToSuspend();
225 cmd->SetId(commandId);
226 if (!deviceId.empty())
228 cmd->SetVolumeReconstructorDeviceId(deviceId.c_str());
237 vtkSmartPointer<vtkPlusReconstructVolumeCommand> cmd = vtkSmartPointer<vtkPlusReconstructVolumeCommand>::New();
238 cmd->SetNameToResume();
239 cmd->SetId(commandId);
240 if (!deviceId.empty())
242 cmd->SetVolumeReconstructorDeviceId(deviceId.c_str());
251 vtkSmartPointer<vtkPlusReconstructVolumeCommand> cmd = vtkSmartPointer<vtkPlusReconstructVolumeCommand>::New();
252 cmd->SetNameToGetSnapshot();
253 cmd->SetId(commandId);
254 if (!deviceId.empty())
256 cmd->SetVolumeReconstructorDeviceId(deviceId.c_str());
258 if (!outputFilename.empty())
260 cmd->SetOutputVolFilename(outputFilename.c_str());
262 if (!outputImageName.empty())
264 cmd->SetOutputVolDeviceName(outputImageName.c_str());
273 vtkSmartPointer<vtkPlusReconstructVolumeCommand> cmd = vtkSmartPointer<vtkPlusReconstructVolumeCommand>::New();
274 cmd->SetNameToStop();
275 cmd->SetId(commandId);
276 if (!deviceId.empty())
278 cmd->SetVolumeReconstructorDeviceId(deviceId.c_str());
280 if (!outputFilename.empty())
282 cmd->SetOutputVolFilename(outputFilename.c_str());
284 if (!outputImageName.empty())
286 cmd->SetOutputVolDeviceName(outputImageName.c_str());
293 #ifdef PLUS_USE_STEALTHLINK 294 PlusStatus ExecuteGetExamData(
vtkPlusOpenIGTLinkClient* client,
const std::string& deviceId,
const std::string& dicomOutputDirectory,
const std::string& volumeEmbeddedTransformToFrame,
295 const bool& keepReceivedDicomFiles,
int commandId)
297 vtkSmartPointer<vtkPlusStealthLinkCommand> cmd = vtkSmartPointer<vtkPlusStealthLinkCommand>::New();
298 cmd->SetNameToGetExam();
299 cmd->SetId(commandId);
300 if (!deviceId.empty())
302 cmd->SetStealthLinkDeviceId(deviceId.c_str());
304 if (!dicomOutputDirectory.empty())
306 cmd->SetDicomImagesOutputDirectory(dicomOutputDirectory.c_str());
308 if (!volumeEmbeddedTransformToFrame.empty())
310 cmd->SetVolumeEmbeddedTransformToFrame(volumeEmbeddedTransformToFrame.c_str());
312 cmd->SetKeepReceivedDicomFiles(keepReceivedDicomFiles);
319 #ifdef PLUS_USE_CLARIUS 321 const double& lastNSeconds,
bool enableCompression,
int commandId)
323 vtkSmartPointer<vtkPlusClariusCommand> cmd = vtkSmartPointer<vtkPlusClariusCommand>::New();
324 cmd->SetNameToSaveRawData();
325 cmd->SetId(commandId);
326 if (!deviceId.empty())
328 cmd->SetClariusDeviceId(deviceId.c_str());
330 if (!outputFilename.empty())
332 cmd->SetOutputFilename(outputFilename);
334 cmd->SetRawDataLastNSeconds(lastNSeconds);
335 cmd->SetCompressRawData(enableCompression);
344 vtkSmartPointer<vtkPlusVersionCommand> cmd = vtkSmartPointer<vtkPlusVersionCommand>::New();
345 cmd->SetNameToVersion();
346 cmd->SetId(commandId);
354 vtkSmartPointer<vtkPlusRequestIdsCommand> cmd = vtkSmartPointer<vtkPlusRequestIdsCommand>::New();
355 cmd->SetNameToRequestChannelIds();
356 cmd->SetId(commandId);
364 vtkSmartPointer<vtkPlusRequestIdsCommand> cmd = vtkSmartPointer<vtkPlusRequestIdsCommand>::New();
365 cmd->SetNameToRequestDeviceIds();
366 cmd->SetId(commandId);
367 cmd->SetDeviceType(deviceType.c_str());
374 const std::string& transformName,
375 const std::string& transformValue,
376 const std::string& transformError,
377 const std::string& transformDate,
378 const std::string& transformPersistent,
int commandId)
380 vtkSmartPointer<vtkPlusUpdateTransformCommand> cmd = vtkSmartPointer<vtkPlusUpdateTransformCommand>::New();
381 cmd->SetNameToUpdateTransform();
382 cmd->SetId(commandId);
383 cmd->SetTransformName(transformName.c_str());
385 igsioCommon::StringToDouble(transformError.c_str(),
value);
386 cmd->SetTransformError(
value);
387 cmd->SetTransformDate(transformDate.c_str());
388 cmd->SetTransformPersistent(igsioCommon::IsEqualInsensitive(transformPersistent,
"TRUE"));
389 std::vector<std::string> elems;
390 vtkMatrix4x4* transformValueMatrix = vtkMatrix4x4::New();
391 igsioCommon::SplitStringIntoTokens(transformValue,
' ', elems);
392 if (elems.size() != 16)
394 LOG_ERROR(
"Invalid formatting of matrix string.");
397 for (
int i = 0;
i < 4;
i++)
399 for (
int j = 0; j < 4; j++)
401 igsioCommon::StringToDouble((elems[
i * 4 + j]).c_str(),
value);
402 transformValueMatrix->SetElement(
i, j,
value);
405 cmd->SetTransformValue(transformValueMatrix);
406 transformValueMatrix->Delete();
414 vtkSmartPointer<vtkPlusGetTransformCommand> cmd = vtkSmartPointer<vtkPlusGetTransformCommand>::New();
415 cmd->SetNameToGetTransform();
416 cmd->SetId(commandId);
417 cmd->SetTransformName(transformName.c_str());
425 vtkNew<vtkPlusIgtlMessageFactory> factory;
426 igtl::MessageBase::Pointer msg = factory->CreateSendMessage(
"GET_POINT", IGTL_HEADER_VERSION_2);
427 msg->AllocateBuffer();
428 msg->SetMetaDataElement(
"Filename", IANA_TYPE_US_ASCII, inputFilename);
436 vtkSmartPointer<vtkPlusSaveConfigCommand> cmd = vtkSmartPointer<vtkPlusSaveConfigCommand>::New();
437 cmd->SetNameToSaveConfig();
438 cmd->SetId(commandId);
439 cmd->SetFilename(outputFilename.c_str());
447 vtkSmartPointer<vtkPlusIgtlMessageFactory> factory = vtkSmartPointer<vtkPlusIgtlMessageFactory>::New();
448 igtl::MessageBase::Pointer msg = factory->CreateSendMessage(
"STT_TDATA", IGTL_HEADER_VERSION_1);
449 igtl::StartTrackingDataMessage* startMsg = dynamic_cast<igtl::StartTrackingDataMessage*>(msg.GetPointer());
450 startMsg->SetResolution(25);
458 vtkSmartPointer<vtkPlusIgtlMessageFactory> factory = vtkSmartPointer<vtkPlusIgtlMessageFactory>::New();
459 igtl::MessageBase::Pointer msg = factory->CreateSendMessage(
"STP_TDATA", IGTL_HEADER_VERSION_1);
460 igtl::StopTrackingDataMessage* stopMsg = dynamic_cast<igtl::StopTrackingDataMessage*>(msg.GetPointer());
468 vtkSmartPointer<vtkPlusSendTextCommand> cmd = vtkSmartPointer<vtkPlusSendTextCommand>::New();
469 cmd->SetNameToSendText();
470 cmd->SetId(commandId);
471 cmd->SetText(
text.c_str());
472 cmd->SetDeviceId(deviceId.c_str());
473 cmd->SetResponseExpected(responseExpected);
481 std::string& outContent,
482 std::string& outErrorMessage,
483 igtl::MessageBase::MetaDataMap& parameters,
487 std::string commandName;
491 const double replyTimeoutSec = timeoutSec;
492 if (client->
ReceiveReply(result, commandId, outErrorMessage, outContent, parameters, commandName, replyTimeoutSec) !=
PLUS_SUCCESS)
494 LOG_ERROR(
"Failed to receive reply to the command");
499 LOG_INFO(
"Command ID: " << commandId);
500 LOG_INFO(
"Status: " << (result ==
PLUS_SUCCESS ?
"SUCCESS" :
"FAIL"));
503 LOG_INFO(
"Error: " << outErrorMessage);
505 LOG_INFO(
"Message: " << outContent);
506 for (igtl::MessageBase::MetaDataMap::const_iterator it = parameters.begin(); it != parameters.end(); ++it)
508 LOG_INFO(it->first <<
": " << it->second.second);
520 if (!vtksys::SystemTools::FileExists(executablePath.c_str(),
true))
522 LOG_ERROR(
"Unable to find executable at: " << executablePath);
528 processPtr = vtksysProcess_New();
531 std::vector<const char*> command;
532 command.push_back(executablePath.c_str());
533 std::string param1 = std::string(
"--config-file=") + configFile;
534 command.push_back(param1.c_str());
535 command.push_back(0);
536 vtksysProcess_SetCommand(processPtr, &*command.begin());
539 vtksysProcess_SetPipeFile(processPtr, vtksysProcess_Pipe_STDOUT,
"PlusServerRemoteControlStdOut.log");
540 vtksysProcess_SetPipeFile(processPtr, vtksysProcess_Pipe_STDERR,
"PlusServerRemoteControlStdErr.log");
542 LOG_INFO(
"Start PlusServer...");
543 vtksysProcess_Execute(processPtr);
544 LOG_DEBUG(
"PlusServer started");
550 LOG_ERROR(
"Failed to start PlusServer");
558 if (processPtr == NULL)
562 vtksysProcess_Kill(processPtr);
566 #define RETURN_IF_FAIL(cmd) if (cmd!=PLUS_SUCCESS) { return PLUS_FAIL; }; 571 const char captureDeviceId[] =
"CaptureDevice";
572 const char capturingOutputFileName[] =
"OpenIGTTrackedVideoRecordingTest.mha";
574 const char volumeReconstructionDeviceId[] =
"VolumeReconstructorDevice";
575 const char* batchReconstructionInputFileName = capturingOutputFileName;
576 const char batchReconstructionOutputImageName[] =
"VolumeReconstructedBatch";
577 const char snapshotReconstructionOutputImageName[] =
"VolumeReconstructedSnapshot";
578 const char liveReconstructionOutputImageName[] =
"VolumeReconstructedLive";
579 const char batchReconstructionOutputFileName[] =
"VolumeReconstructedBatch.nrrd";
580 const char snapshotReconstructionOutputFileName[] =
"VolumeReconstructedSnapshot.nrrd";
581 const char liveReconstructionOutputFileName[] =
"VolumeReconstructedLive.nrrd";
583 std::string replyMessage;
584 std::string errorMessage;
585 igtl::MessageBase::MetaDataMap parameters;
587 bool didTimeout(
false);
589 if (client->GetServerIGTLVersion() >= OpenIGTLink_PROTOCOL_VERSION_3)
593 if (result ==
PLUS_FAIL && didTimeout && client->GetServerIGTLVersion() >= OpenIGTLink_PROTOCOL_VERSION_3)
596 LOG_ERROR(
"Version handshake to the server timed out but it was unexpected.");
599 else if (result ==
PLUS_SUCCESS && parameters.find(
"Version") != parameters.end())
601 LOG_INFO(
"Server IGTL Version: " << parameters[
"Version"].second);
605 LOG_ERROR(
"Version handshake to the server failed.");
614 if (client->GetServerIGTLVersion() < OpenIGTLink_PROTOCOL_VERSION_3)
616 if (replyMessage !=
"TrackedVideoStream")
618 LOG_ERROR(
"Incorrect reply sent. Got: " << replyMessage <<
". Expected: \"TrackedVideoStream\"");
623 if (parameters.size() == 0 || parameters.find(
"TrackedVideoStream") == parameters.end())
625 LOG_ERROR(
"Empty result or entry not found in list of device IDs.");
629 if (!igsioCommon::IsEqualInsensitive(parameters[
"TrackedVideoStream"].second,
"TrackedVideoStream"))
631 LOG_ERROR(
"Incorrect parameter returned. Got: " << parameters[
"TrackedVideoStream"].second <<
". Expected: \"TrackedVideoStream\"");
639 if (client->GetServerIGTLVersion() < OpenIGTLink_PROTOCOL_VERSION_3)
641 if (replyMessage !=
"VolumeReconstructorDevice")
643 LOG_ERROR(
"Incorrect reply sent. Got: " << replyMessage <<
". Expected: \"VolumeReconstructorDevice\"");
648 if (parameters.size() == 0)
650 LOG_ERROR(
"Empty result returned for list of device IDs.");
654 if (!igsioCommon::IsEqualInsensitive(parameters[
"VolumeReconstructorDevice"].second,
"VolumeReconstructorDevice"))
656 LOG_ERROR(
"Incorrect parameter returned.");
662 ExecuteUpdateTransform(client,
"Test1ToReference",
"1 0 0 10 0 1.2 0.1 12 0.1 0.2 -0.9 -20 0 0 0 1",
"1.4",
"100314_182141",
"TRUE", commandId++);
682 vtkIGSIOAccurateTimer::DelayWithEventProcessing(2.0);
686 vtkIGSIOAccurateTimer::DelayWithEventProcessing(2.0);
690 vtkIGSIOAccurateTimer::DelayWithEventProcessing(2.0);
694 vtkIGSIOAccurateTimer::DelayWithEventProcessing(2.0);
697 ExecuteReconstructFromFile(client, volumeReconstructionDeviceId, batchReconstructionInputFileName, batchReconstructionOutputFileName, batchReconstructionOutputImageName, commandId++);
700 vtkIGSIOAccurateTimer::DelayWithEventProcessing(2.0);
706 vtkIGSIOAccurateTimer::DelayWithEventProcessing(2.0);
710 vtkIGSIOAccurateTimer::DelayWithEventProcessing(2.0);
714 vtkIGSIOAccurateTimer::DelayWithEventProcessing(2.0);
715 ExecuteGetSnapshotReconstruction(client, volumeReconstructionDeviceId, snapshotReconstructionOutputFileName, snapshotReconstructionOutputImageName, commandId++);
718 vtkIGSIOAccurateTimer::DelayWithEventProcessing(2.0);
719 ExecuteGetSnapshotReconstruction(client, volumeReconstructionDeviceId, snapshotReconstructionOutputFileName, snapshotReconstructionOutputImageName, commandId++);
722 vtkIGSIOAccurateTimer::DelayWithEventProcessing(2.0);
723 ExecuteGetSnapshotReconstruction(client, volumeReconstructionDeviceId, snapshotReconstructionOutputFileName, snapshotReconstructionOutputImageName, commandId++);
726 vtkIGSIOAccurateTimer::DelayWithEventProcessing(2.0);
727 ExecuteStopReconstruction(client, volumeReconstructionDeviceId, liveReconstructionOutputFileName, liveReconstructionOutputImageName, commandId++);
730 vtkIGSIOAccurateTimer::DelayWithEventProcessing(2.0);
743 int main(
int argc,
char** argv)
746 std::string serverHost =
"127.0.0.1";
747 int serverPort = 18944;
749 std::string deviceId;
750 std::string inputFilename =
"PlusServerRecording.nrrd";
751 std::string outputFilename;
752 std::string outputImageName;
753 std::string transformName;
754 std::string transformError;
755 std::string transformDate;
756 std::string transformPersistent;
757 std::string transformValue;
758 std::string dicomOutputDirectory;
759 std::string volumeEmbeddedTransformToFrame;
760 int serverHeaderVersion(-1);
762 bool keepReceivedDicomFiles =
false;
763 bool responseExpected =
false;
764 bool enableCompression =
false;
765 int verboseLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED;
766 bool keepConnected =
false;
767 std::string serverConfigFileName;
768 bool runTests =
false;
769 int serverIGTLVersion(-1);
771 double lastNSeconds(-1.0);
773 vtksys::CommandLineArguments args;
774 args.Initialize(argc, argv);
776 args.AddArgument(
"--host", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &serverHost,
"Host name of the OpenIGTLink server (default: 127.0.0.1)");
777 args.AddArgument(
"--port", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &serverPort,
"Port address of the OpenIGTLink server (default: 18944)");
778 args.AddArgument(
"--command", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &command,
779 "Command name to be executed on the server (START_ACQUISITION, STOP_ACQUISITION, SUSPEND_ACQUISITION, RESUME_ACQUISITION, RECONSTRUCT, START_RECONSTRUCTION, SUSPEND_RECONSTRUCTION, RESUME_RECONSTRUCTION, STOP_RECONSTRUCTION, GET_RECONSTRUCTION_SNAPSHOT, GET_CHANNEL_IDS, GET_DEVICE_IDS, GET_EXAM_DATA, SAVE_RAW_DATA, SEND_TEXT, UPDATE_TRANSFORM, GET_TRANSFORM, GET_POINT)");
780 args.AddArgument(
"--command-id", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &commandId,
"Command ID to send to the server.");
781 args.AddArgument(
"--server-igtl-version", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &serverHeaderVersion,
"The version of IGTL used by the server. Remove this parameter when querying is dynamic.");
782 args.AddArgument(
"--device", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &deviceId,
"ID of the controlled device (optional, default: first VirtualStreamCapture or VirtualVolumeReconstructor device). In case of GET_DEVICE_IDS it is not an ID but a device type.");
783 args.AddArgument(
"--input-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputFilename,
"File name of the input, used for RECONSTRUCT command");
784 args.AddArgument(
"--output-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &outputFilename,
"File name of the output, used for START command (optional, default: 'PlusServerRecording.nrrd' for acquisition, no output for volume reconstruction)");
785 args.AddArgument(
"--output-image-name", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &outputImageName,
"OpenIGTLink device name of the reconstructed file (optional, default: image is not sent)");
786 args.AddArgument(
"--text", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &
text,
"Text to be sent to the device");
787 args.AddArgument(
"--transform-name", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &transformName,
"The name of the transform to update. Form=[From]To[To]Transform");
788 args.AddArgument(
"--transform-date", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &transformDate,
"The date of the transform to update.");
789 args.AddArgument(
"--transform-error", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &transformError,
"The error of the transform to update.");
790 args.AddArgument(
"--transform-persistent", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &transformPersistent,
"The persistence of the transform to update.");
791 args.AddArgument(
"--transform-value", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &transformValue,
"The actual transformation matrix to update.");
792 args.AddArgument(
"--use-compression", vtksys::CommandLineArguments::NO_ARGUMENT, &enableCompression,
"Set capture device to record compressed data. Only supported with .nrrd capture.");
793 args.AddArgument(
"--keep-connected", vtksys::CommandLineArguments::NO_ARGUMENT, &keepConnected,
"Keep the connection to the server after command completion (exits on CTRL-C).");
794 args.AddArgument(
"--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel,
"Verbose level (1=error only, 2=warning, 3=info, 4=debug, 5=trace)");
795 args.AddArgument(
"--dicom-directory", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &dicomOutputDirectory,
"The folder directory for the dicom images acquired from the StealthLink Server");
796 args.AddArgument(
"--volumeEmbeddedTransformToFrame", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &volumeEmbeddedTransformToFrame,
"The reference frame in which the dicom image will be represented. Ex: RAS,LPS,Reference,Tracker etc");
797 args.AddArgument(
"--keepReceivedDicomFiles", vtksys::CommandLineArguments::NO_ARGUMENT, &keepReceivedDicomFiles,
"Keep the dicom files in the designated folder after having acquired them from the server");
798 args.AddArgument(
"--response-expected", vtksys::CommandLineArguments::NO_ARGUMENT, &responseExpected,
"Wait for a response after sending text");
799 args.AddArgument(
"--server-config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &serverConfigFileName,
"Starts a PlusServer instance with the provided config file. When this process exits, the server is stopped.");
800 args.AddArgument(
"--run-tests", vtksys::CommandLineArguments::NO_ARGUMENT, &runTests,
"Test execution of all remote control commands. Requires a running PlusServer, which can be launched by --server-config-file");
801 args.AddArgument(
"--last-n-seconds", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &lastNSeconds,
"Number of seconds of raw data to acquire from Clarius");
805 std::cerr <<
"Problem parsing arguments." << std::endl;
806 std::cout <<
"Help: " << args.GetHelp() << std::endl;
810 if (command.empty() && !keepConnected && !runTests)
812 LOG_ERROR(
"The program has nothing to do, as neither --command, --keep-connected, nor --run-tests is specifed");
813 std::cout <<
"Help: " << args.GetHelp() << std::endl;
820 vtksysProcess* plusServerProcess = NULL;
821 if (!serverConfigFileName.empty())
825 LOG_ERROR(
"Failed to start PlusServer");
832 vtkSmartPointer<vtkPlusOpenIGTLinkClient> client = vtkSmartPointer<vtkPlusOpenIGTLinkClient>::New();
836 client = vtkSmartPointer<vtkPlusOpenIGTLinkClientWithTransformLogging>::New();
838 client->SetServerHost(serverHost.c_str());
839 client->SetServerPort(serverPort);
840 if (serverIGTLVersion > 0)
842 client->SetServerIGTLVersion(serverIGTLVersion);
846 LOG_ERROR(
"Failed to connect to server at " << serverHost <<
":" << serverPort);
851 int processReturnValue = EXIT_SUCCESS;
854 if (!command.empty())
858 if (igsioCommon::IsEqualInsensitive(command,
"START_ACQUISITION"))
860 commandExecutionStatus =
ExecuteStartAcquisition(client, deviceId, outputFilename, enableCompression, commandId);
862 else if (igsioCommon::IsEqualInsensitive(command,
"STOP_ACQUISITION"))
866 else if (igsioCommon::IsEqualInsensitive(command,
"SUSPEND_ACQUISITION"))
870 else if (igsioCommon::IsEqualInsensitive(command,
"RESUME_ACQUISITION"))
874 else if (igsioCommon::IsEqualInsensitive(command,
"START_RECONSTRUCTION"))
878 else if (igsioCommon::IsEqualInsensitive(command,
"SUSPEND_RECONSTRUCTION"))
882 else if (igsioCommon::IsEqualInsensitive(command,
"RESUME_RECONSTRUCTION"))
886 else if (igsioCommon::IsEqualInsensitive(command,
"GET_RECONSTRUCTION_SNAPSHOT"))
890 else if (igsioCommon::IsEqualInsensitive(command,
"STOP_RECONSTRUCTION"))
894 else if (igsioCommon::IsEqualInsensitive(command,
"RECONSTRUCT"))
896 commandExecutionStatus =
ExecuteReconstructFromFile(client, deviceId, inputFilename, outputFilename, outputImageName, commandId);
898 else if (igsioCommon::IsEqualInsensitive(command,
"GET_CHANNEL_IDS"))
902 else if (igsioCommon::IsEqualInsensitive(command,
"GET_DEVICE_IDS"))
906 else if (igsioCommon::IsEqualInsensitive(command,
"UPDATE_TRANSFORM"))
908 commandExecutionStatus =
ExecuteUpdateTransform(client, transformName, transformValue, transformError, transformDate, transformPersistent, commandId);
910 else if (igsioCommon::IsEqualInsensitive(command,
"SAVE_CONFIG"))
914 else if (igsioCommon::IsEqualInsensitive(command,
"SEND_TEXT"))
916 commandExecutionStatus =
ExecuteSendText(client, deviceId,
text, responseExpected, commandId);
918 else if (igsioCommon::IsEqualInsensitive(command,
"GET_TRANSFORM"))
922 else if (igsioCommon::IsEqualInsensitive(command,
"GET_POINT"))
926 else if (igsioCommon::IsEqualInsensitive(command,
"GET_EXAM_DATA"))
928 #ifdef PLUS_USE_STEALTHLINK 929 commandExecutionStatus = ExecuteGetExamData(client, deviceId, dicomOutputDirectory, volumeEmbeddedTransformToFrame, keepReceivedDicomFiles, commandId);
931 LOG_ERROR(
"Plus is not built with StealthLink support");
935 else if (igsioCommon::IsEqualInsensitive(command,
"SAVE_RAW_DATA"))
937 #ifdef PLUS_USE_CLARIUS 938 commandExecutionStatus = ExecuteSaveRawData(client, deviceId, outputFilename, lastNSeconds, enableCompression, commandId);
940 LOG_ERROR(
"Plus is not built with Clarius support");
946 LOG_ERROR(
"Unknown command: " << command);
947 client->Disconnect();
952 std::string replyMessage;
953 std::string errorMessage;
955 igtl::MessageBase::MetaDataMap parameters;
958 processReturnValue = EXIT_FAILURE;
964 processReturnValue = EXIT_FAILURE;
978 processReturnValue = EXIT_FAILURE;
987 std::cout <<
"Press Ctrl-C to quit:" << std::endl;
991 const double commandQueuePollIntervalSec = 0.010;
995 vtkIGSIOAccurateTimer::DelayWithEventProcessing(commandQueuePollIntervalSec);
999 client->Disconnect();
1001 return processReturnValue;
PlusStatus ExecuteSendText(vtkPlusOpenIGTLinkClient *client, const std::string &deviceId, const std::string &text, bool responseExpected, int commandId)
PlusStatus ExecuteStartTDATA(vtkPlusOpenIGTLinkClient *client, int commandId)
PlusStatus ExecuteStartReconstruction(vtkPlusOpenIGTLinkClient *client, const std::string &deviceId, int commandId)
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *aConfig)
static bool StopClientRequested
std::string GetPlusExecutablePath(const std::string &executableName)
This is an abstract superclass for commands in the OpenIGTLink network interface for Plus.
igtlUint64 SocketReceive(void *data, igtlUint64 length)
#define RETURN_IF_FAIL(cmd)
PlusStatus SendMessage(igtl::MessageBase::Pointer packedMessage)
int main(int argc, char **argv)
PlusStatus RunTests(vtkPlusOpenIGTLinkClient *client)
PlusStatus ExecuteGetPoint(vtkPlusOpenIGTLinkClient *client, const std::string &inputFilename)
PlusStatus ReceiveAndPrintReply(vtkPlusOpenIGTLinkClient *client, bool &didTimeout, std::string &outContent, std::string &outErrorMessage, igtl::MessageBase::MetaDataMap ¶meters, int timeoutSec=30)
PlusStatus ExecuteSuspendReconstruction(vtkPlusOpenIGTLinkClient *client, const std::string &deviceId, int commandId)
static vtkPlusConfig * GetInstance()
PlusStatus ExecuteStopTDATA(vtkPlusOpenIGTLinkClient *client, int commandId)
PlusStatus StartPlusServerProcess(const std::string &configFile, vtksysProcess *&processPtr)
PlusStatus ExecuteVersion(vtkPlusOpenIGTLinkClient *client, int commandId)
PhidgetLCD_Font int int const char * text
static vtkPlusOpenIGTLinkClient * New()
PlusStatus ExecuteSuspendAcquisition(vtkPlusOpenIGTLinkClient *client, const std::string &deviceId, int commandId)
PlusStatus ExecuteUpdateTransform(vtkPlusOpenIGTLinkClient *client, const std::string &transformName, const std::string &transformValue, const std::string &transformError, const std::string &transformDate, const std::string &transformPersistent, int commandId)
PlusStatus ExecuteGetTransform(vtkPlusOpenIGTLinkClient *client, const std::string &transformName, int commandId)
PlusStatus ExecuteReconstructFromFile(vtkPlusOpenIGTLinkClient *client, const std::string &deviceId, const std::string &inputFilename, const std::string &outputFilename, const std::string &outputImageName, int commandId)
PlusStatus ExecuteStopReconstruction(vtkPlusOpenIGTLinkClient *client, const std::string &deviceId, const std::string &outputFilename, const std::string &outputImageName, int commandId)
PlusStatus ExecuteSaveConfig(vtkPlusOpenIGTLinkClient *client, const std::string &outputFilename, int commandId)
const char const char * value
PlusStatus ExecuteResumeAcquisition(vtkPlusOpenIGTLinkClient *client, const std::string &deviceId, int commandId)
PlusStatus ExecuteStartAcquisition(vtkPlusOpenIGTLinkClient *client, const std::string &deviceId, std::string outputFilename, bool enableCompression, int commandId)
virtual bool OnMessageReceived(igtl::MessageHeader::Pointer messageHeader)
static vtkIGSIOLogger * Instance()
PlusStatus ExecuteGetChannelIds(vtkPlusOpenIGTLinkClient *client, int commandId)
PlusStatus ExecuteResumeReconstruction(vtkPlusOpenIGTLinkClient *client, const std::string &deviceId, int commandId)
This class provides a network interface to access Plus functions as an OpenIGTLink client.
void StopPlusServerProcess(vtksysProcess *&processPtr)
void SignalInterruptHandler(int s)
void PrintCommand(vtkPlusCommand *command)
PlusStatus ExecuteGetSnapshotReconstruction(vtkPlusOpenIGTLinkClient *client, const std::string &deviceId, const std::string &outputFilename, const std::string &outputImageName, int commandId)
vtkStandardNewMacro(vtkPlusOpenIGTLinkClientWithTransformLogging)
PlusStatus ExecuteStopAcquisition(vtkPlusOpenIGTLinkClient *client, const std::string &deviceId, std::string outputFilename, int commandId)
PlusStatus ReceiveReply(PlusStatus &result, int32_t &outOriginalCommandId, std::string &outErrorString, std::string &outContent, igtl::MessageBase::MetaDataMap &outParameters, std::string &outCommandName, double timeoutSec=0)
PlusStatus ExecuteGetDeviceIds(vtkPlusOpenIGTLinkClient *client, const std::string &deviceType, int commandId)
PlusStatus SendCommand(vtkPlusCommand *command)