7 #include "PlusConfigure.h" 12 #include "vtkMatrix4x4.h" 13 #include "vtkObjectFactory.h" 15 #include "vtkTransform.h" 16 #include "vtkXMLDataElement.h" 17 #include "vtkXMLUtilities.h" 18 #include "vtksys/SystemTools.hxx" 56 this->OrientationSensorTool = NULL;
58 this->FirmwareDefinition = vtkXMLDataElement::New();
77 this->Serial->
Close();
82 this->FirmwareDefinition->Delete();
83 this->FirmwareDefinition = NULL;
95 LOG_TRACE(
"vtkPlusChRoboticsTracker::Connect");
99 LOG_ERROR(
"Already connected to serial port");
103 std::ostringstream strComPort;
104 strComPort <<
"COM" << this->SerialPort;
105 this->Serial->SetPortName(strComPort.str());
111 if (!this->Serial->
Open())
113 LOG_ERROR(
"Cannot open serial port " << strComPort.str());
119 LOG_ERROR(
"COM port handle is not alive " << strComPort.str());
125 LOG_ERROR(
"Failed to load firmware description for the connected device");
126 this->Serial->
Close();
132 LOG_ERROR(
"Failed to update data item descriptors from firmware description");
133 this->Serial->
Close();
137 this->OrientationSensorTool = NULL;
146 LOG_TRACE(
"vtkPlusChRoboticsTracker::Disconnect");
149 this->Serial->
Close();
151 this->OrientationSensorTool = NULL;
158 LOG_TRACE(
"vtkPlusChRoboticsTracker::Probe");
160 LOG_ERROR(
"vtkPlusChRoboticsTracker::Probe is not implemented");
168 LOG_TRACE(
"vtkPlusChRoboticsTracker::InternalStartRecording");
175 LOG_TRACE(
"vtkPlusChRoboticsTracker::InternalStopRecording");
182 LOG_TRACE(
"vtkPlusChRoboticsTracker::InternalUpdate");
194 const double unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
196 if (this->OrientationSensorTool != NULL)
198 vtkSmartPointer<vtkMatrix4x4> orientationSensorToTracker = vtkSmartPointer<vtkMatrix4x4>::New();
202 vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
203 transform->RotateX(this->EulerRoll.
GetValue());
204 transform->RotateY(this->EulerPitch.
GetValue());
205 transform->RotateZ(this->EulerYaw.
GetValue());
206 transform->GetMatrix(orientationSensorToTracker);
209 unsigned long frameNumber = this->OrientationSensorTool->GetFrameNumber() + 1 ;
210 ToolTimeStampedUpdate(this->OrientationSensorTool->GetId(), orientationSensorToTracker, TOOL_OK, frameNumber, unfilteredTimestamp);
220 LOG_DEBUG(
"Loading the firmware files from " << firmwareFullPath);
222 std::vector<std::string> firmwareFileList;
224 if (firmwareFileList.size() == 0)
226 LOG_ERROR(
"Failed to load firmware definitions from " << firmwareFullPath);
230 for (std::vector<std::string>::iterator it = firmwareFileList.begin(); it != firmwareFileList.end(); ++it)
232 LOG_DEBUG(
"Loading firmware from: " << (*it));
233 vtkSmartPointer<vtkXMLDataElement> firmwareElemRoot = vtkSmartPointer<vtkXMLDataElement>::Take(vtkXMLUtilities::ReadElementFromFile((*it).c_str()));
234 if (firmwareElemRoot.GetPointer() == NULL)
236 LOG_WARNING(
"Failed to read firmware definition from " << (*it) <<
". The file is ignored.");
239 const char* foundFirmwareId = firmwareElemRoot->GetAttribute(
"id");
240 if (foundFirmwareId == NULL)
242 LOG_WARNING(
"Id not found in firmware definition file " << (*it) <<
". The file is ignored.");
246 if (requestedFirmwareId.compare(foundFirmwareId) == 0)
249 foundDefinition->DeepCopy(firmwareElemRoot);
254 foundDefinition->RemoveAllAttributes();
255 foundDefinition->RemoveAllNestedElements();
256 LOG_ERROR(
"Could not find ChRobotics firmware definition for attached device (" << requestedFirmwareId <<
")");
263 #ifdef _WIN32 // Windows 265 std::string findPath = dir +
"\\*.*";
266 long currentPosition = _findfirst(findPath.c_str(), &file);
267 if (currentPosition == -1L)
273 std::string fileName = file.name;
275 if (strcmp(fileName.c_str(),
".") != 0 && strcmp(fileName.c_str(),
"..") != 0)
278 if (!(file.attrib & _A_SUBDIR))
280 fileNames.push_back(std::string(dir) +
"/" + fileName);
284 while (_findnext(currentPosition, &file) == 0);
285 _findclose(currentPosition);
289 if ((d = opendir(dir.c_str())) != NULL)
291 while ((ent = readdir(d)) != NULL)
293 std::string entry(ent->d_name);
294 if (entry !=
"." && entry !=
"..")
296 fileNames.push_back(dir +
"/" + entry);
328 if (this->FirmwareDefinition == NULL)
330 LOG_ERROR(
"Firmware definition is not available");
334 const std::string dataGroupElemName =
"DataGroup";
335 const std::string dataItemElemName =
"DataItem";
337 for (
int dataGroupIndex = 0; dataGroupIndex < this->FirmwareDefinition->GetNumberOfNestedElements(); ++dataGroupIndex)
339 vtkXMLDataElement* groupElem = this->FirmwareDefinition->GetNestedElement(dataGroupIndex);
340 if (groupElem == NULL)
344 if (dataGroupElemName.compare(groupElem->GetName()) != 0)
349 for (
int dataItemIndex = 0; dataItemIndex < groupElem->GetNumberOfNestedElements(); ++dataItemIndex)
351 vtkXMLDataElement* dataItemElem = groupElem->GetNestedElement(dataItemIndex);
353 if (dataItemElemName.compare(dataItemElem->GetName()) != 0)
359 vtkXMLDataElement* dataItemNameElem = dataItemElem->FindNestedElementWithName(
"Name");
360 if (dataItemNameElem == NULL)
365 if (itemName.compare(dataItemNameElem->GetCharacterData()) != 0)
375 LOG_ERROR(
"Data item desctiption not found: " << itemName);
382 LOG_TRACE(
"vtkPlusChRoboticsTracker::LoadFirmwareDescriptionForConnectedDevice");
383 this->FirmwareVersionId.clear();
394 LOG_ERROR(
"Failed to query ChRobotics device firmware version");
400 for (
int i = 0;
i < dataLength;
i++)
402 this->FirmwareVersionId.push_back(fwReply.
GetDataByte(
i));
409 LOG_ERROR(
"Failed to load firmware definition for ChRobotics device version " << this->FirmwareVersionId);
413 LOG_INFO(
"CHRobotics device firmware identified (" << this->FirmwareVersionId <<
") and firmware definition loaded.");
433 LOG_ERROR(
"Failed to receive reply to command " <<
int(requestPacket.
GetAddress()));
440 std::vector<unsigned char> data_array;
444 for (
int i = 0;
i < packetLength;
i++)
449 LOG_TRACE(
"Sent packet: address=" <<
int(packet.
GetAddress()) <<
", data length=" <<
int(packet.
GetDataLength()));
458 std::deque<unsigned char> lastThreeChars;
460 this->Serial->
Read(d);
461 lastThreeChars.push_back(d);
462 this->Serial->
Read(d);
463 lastThreeChars.push_back(d);
464 this->Serial->
Read(d);
465 lastThreeChars.push_back(d);
466 while (lastThreeChars[0] !=
's' || lastThreeChars[1] !=
'n' || lastThreeChars[2] !=
'p')
468 lastThreeChars.pop_front();
469 if (!this->Serial->
Read(d))
471 LOG_ERROR(
"Failed to read packet header (start sequence) through serial line");
474 lastThreeChars.push_back(d);
477 if (!this->Serial->
Read(d))
479 LOG_ERROR(
"Failed to read packet header (packet descriptor) through serial line");
484 if (!this->Serial->
Read(d))
486 LOG_ERROR(
"Failed to read packet header (address) through serial line");
493 for (
int i = 0;
i < dataLength;
i++)
495 if (!this->Serial->
Read(d))
497 LOG_ERROR(
"Failed to read packet data[" <<
i <<
"] through serial line");
503 unsigned char checksum0 = 0;
504 if (!this->Serial->
Read(checksum0))
506 LOG_ERROR(
"Failed to read packet checksum[0] through serial line");
509 unsigned char checksum1 = 0;
510 if (!this->Serial->
Read(checksum1))
512 LOG_ERROR(
"Failed to read packet checksum[1] through serial line");
521 LOG_ERROR(
"Received a packet with bad checksum through serial line (" 522 <<
"address=" <<
int(packet.
GetAddress()) <<
", checksum: " 523 <<
int(packet.
GetChecksumByte(0)) <<
"!=" <<
int(checksum0) <<
" and/or " 529 LOG_TRACE(
"Received packet: address=" <<
int(packet.
GetAddress()) <<
", data length=" <<
int(packet.
GetDataLength()));
541 LOG_WARNING(
"Received ChRobotics sensor reply: BAD_CHECKSUM");
546 LOG_WARNING(
"Received ChRobotics sensor reply: UNKNOWN_ADDRESS");
551 LOG_WARNING(
"Received ChRobotics sensor reply: INVALID_BATCH_SIZE");
572 LOG_WARNING(
"Improperly formatted packet: commands should never contain data");
598 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
unsigned long, SerialPort, deviceConfig);
599 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
unsigned long, BaudRate, deviceConfig);
600 XML_READ_CSTRING_ATTRIBUTE_OPTIONAL(FirmwareDirectory, deviceConfig);
608 trackerConfig->SetUnsignedLongAttribute(
"SerialPort", this->SerialPort);
609 trackerConfig->SetUnsignedLongAttribute(
"BaudRate", this->BaudRate);
virtual PlusStatus InternalDisconnect()
unsigned char GetDataLength()
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
bool ReadValueFromPacket(ChrSerialPacket &packet)
int Write(const BYTE *data, int numberOfBytesToWrite)
PlusStatus LoadFirmwareDescriptionForConnectedDevice()
static const int MAX_COMMAND_REPLY_WAIT
PlusStatus FindDataItemDescriptor(const std::string itemName, ChrDataItem &foundItem)
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(deviceConfig, rootConfigElement)
void SetMaxReplyTime(int maxreply)
int Read(BYTE *data, int maxNumberOfBytesToRead)
static const unsigned char UM6_BAD_CHECKSUM
PlusStatus ReadDescriptionFromXml(vtkXMLDataElement *dataItemElem)
void SetBatchEnable(bool enable)
virtual PlusStatus ToolTimeStampedUpdate(const std::string &aToolSourceId, vtkMatrix4x4 *matrix, ToolStatus status, unsigned long frameNumber, double unfilteredtimestamp, const igsioFieldMapType *customFields=NULL)
bool RequirePortNameInDeviceSetConfiguration
void SetHasData(bool has_data)
unsigned char GetChecksumByte(int index)
PlusStatus FindFirmwareDefinition(const std::string &id, vtkXMLDataElement *foundDefinition)
~vtkPlusChRoboticsTracker()
vtkPlusChRoboticsTracker()
unsigned char GetPacketByte(int index)
static vtkPlusConfig * GetInstance()
Class for reading and writing data through the serial (RS-232) port.
void SetPacketDescriptor(unsigned char packetDescriptor)
void GetFileNamesFromDirectory(std::vector< std::string > &fileNames, const std::string &dir)
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *config)
PlusStatus UpdateDataItemDescriptors()
void SetAddress(unsigned char address)
unsigned char GetDataByte(int index)
PlusStatus ProcessPacket(ChrSerialPacket &packet)
static const unsigned char DATA_REGISTER_START_ADDRESS
PlusStatus SendPacket(ChrSerialPacket &packet)
vtkStandardNewMacro(vtkPlusChRoboticsTracker)
PlusStatus GetToolByPortName(const char *aPortName, vtkPlusDataSource *&aSource)
Interface for the CH Robotics CHR-UM6 tracker.
void UpdateDataItemValues(ChrSerialPacket &packet)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *config)
virtual PlusStatus StopRecording()
PlusStatus InternalStartRecording()
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement)
void SetDataByte(int index, unsigned char value)
void ComputeChecksum(void)
unsigned char GetPacketLength()
PlusStatus InternalUpdate()
void PrintSelf(ostream &os, vtkIndent indent)
unsigned char GetAddress()
bool StartThreadForInternalUpdates
unsigned int GetNumberOfBytesAvailableForReading() const
static const unsigned char COMMAND_START_ADDRESS
PlusStatus InternalStopRecording()
std::string GetDeviceSetConfigurationPath(const std::string &subPath)
PlusStatus ReceivePacket(ChrSerialPacket &packet)
PlusStatus SendCommand(ChrSerialPacket &requestPacket, ChrSerialPacket &replyPacket)
static const unsigned char UM6_INVALID_BATCH_SIZE
PlusStatus InternalConnect()
void SetSerialPortSpeed(DWORD speed)
bool IsHandleAlive() const
static const unsigned char UM6_GET_FW_VERSION
static const unsigned char UM6_UNKNOWN_ADDRESS