00001 /*! \file Cmt3.cpp 00002 00003 For information about objects in this file, see the appropriate header: 00004 \ref Cmt3.h 00005 00006 \section FileCopyright Copyright Notice 00007 Copyright (C) Xsens Technologies B.V., 2006. All rights reserved. 00008 00009 This source code is intended for use only by Xsens Technologies BV and 00010 those that have explicit written permission to use it from 00011 Xsens Technologies BV. 00012 00013 THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 00014 KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 00015 IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 00016 PARTICULAR PURPOSE. 00017 00018 \section FileChangelog Changelog 00019 \par 2006-04-28, v0.0.1 00020 \li Job Mulder: Created 00021 \par 2006-07-21, v0.1.0 00022 \li Job Mulder: Updated file for release 0.1.0 00023 */ 00024 00025 #include "cmt3.h" 00026 #include <math.h> 00027 #include "xsens_janitors.h" 00028 00029 #ifdef _LOG_CMT3 00030 # define CMT3LOG CMTLOG 00031 # define CMT3EXITLOG JanitorLogFunc<XsensResultValue,uint32_t> _cmtExitLog(CMTLOG,"L3: " __FUNCTION__ " returns %u\n",m_lastResult); 00032 #else 00033 # define CMT3LOG(...) 00034 # define CMT3EXITLOG 00035 #endif 00036 00037 #ifdef _LOG_CMT3_DATA 00038 # define CMT3LOGDAT CMTLOG 00039 # define CMT3EXITLOGDAT JanitorLogFunc<XsensResultValue,uint32_t> _cmtExitLog(CMTLOG,"L3: " __FUNCTION__ " returns %u\n",m_lastResult); 00040 #else 00041 # define CMT3LOGDAT(...) 00042 # define CMT3EXITLOGDAT 00043 #endif 00044 00045 #define CMT3F_DEVINFO_SIZE (sizeof(CmtDeviceId) + sizeof(CmtDataFormat)) 00046 00047 ////////////////////////////////////////////////////////////////////////////////////////// 00048 //////////////////////////////////// Support classes //////////////////////////////////// 00049 ////////////////////////////////////////////////////////////////////////////////////////// 00050 00051 void CmtDeviceConfiguration::readFromMessage(const void* message) 00052 { 00053 xsens::Message msg((const uint8_t*) message,0); 00054 00055 m_masterDeviceId = msg.getDataLong(0); 00056 m_samplingPeriod = msg.getDataShort(4); 00057 m_outputSkipFactor = msg.getDataShort(6); 00058 m_syncinMode = msg.getDataShort(8); 00059 m_syncinSkipFactor = msg.getDataShort(10); 00060 m_syncinOffset = msg.getDataLong(12); 00061 memcpy(m_date,msg.getDataBuffer(16),8); 00062 memcpy(m_time,msg.getDataBuffer(24),8); 00063 memcpy(m_reservedForHost,msg.getDataBuffer(32),32); 00064 memcpy(m_reservedForClient,msg.getDataBuffer(64),32); 00065 m_numberOfDevices = msg.getDataShort(96); 00066 00067 for (uint16_t i = 0; i < m_numberOfDevices && i < CMT_MAX_DEVICES_PER_PORT; ++i) 00068 { 00069 m_deviceInfo[i].m_deviceId = msg.getDataLong(98+i*20); 00070 m_deviceInfo[i].m_dataLength = msg.getDataShort(102+i*20); 00071 m_deviceInfo[i].m_outputMode = msg.getDataShort(104+i*20); 00072 m_deviceInfo[i].m_outputSettings = msg.getDataLong(106+i*20); 00073 m_deviceInfo[i].m_currentScenario = msg.getDataShort(110+i*20); 00074 m_deviceInfo[i].m_fwRevMajor = msg.getDataByte(112+i*20); 00075 m_deviceInfo[i].m_fwRevMinor = msg.getDataByte(113+i*20); 00076 m_deviceInfo[i].m_fwRevRevision = msg.getDataByte(114+i*20); 00077 m_deviceInfo[i].m_filterType = msg.getDataByte(115+i*20); 00078 m_deviceInfo[i].m_filterMajor = msg.getDataByte(116+i*20); 00079 m_deviceInfo[i].m_filterMinor = msg.getDataByte(117+i*20); 00080 } 00081 } 00082 00083 ////////////////////////////////////////////////////////////////////////////////////////// 00084 // Compute the period and skip factor. 00085 void CmtDeviceMode::getPeriodAndSkipFactor(uint16_t& period,uint16_t& skip) const 00086 { 00087 if (m_sampleFrequency == 0) 00088 { 00089 period = 0; 00090 skip = 0; 00091 return; 00092 } 00093 if (m_sampleFrequency >= 512) 00094 { 00095 period = 225; 00096 skip = 0; 00097 return; 00098 } 00099 00100 int32_t freq, sf = m_sampleFrequency; 00101 00102 // first try the simple ones 00103 skip = 0; 00104 freq = sf; 00105 if (120 % freq == 0 && freq < 120) { 00106 freq = 120; 00107 } else if (100 % freq == 0 && freq < 100) { 00108 freq = 100; 00109 } 00110 while (freq < 100) 00111 { 00112 ++skip; 00113 freq += sf; 00114 } 00115 00116 period = (uint16_t) (115200 / freq); 00117 } 00118 00119 ////////////////////////////////////////////////////////////////////////////////////////// 00120 // Return the real sample frequency in Hz 00121 double CmtDeviceMode::getRealSampleFrequency(void) const 00122 { 00123 uint16_t skip, period; 00124 getPeriodAndSkipFactor(period,skip); 00125 return (115200.0 / ((1.0 + (double) skip) * (double) period)); 00126 } 00127 00128 ////////////////////////////////////////////////////////////////////////////////////////// 00129 // Compute sample frequency from the period and skip factor. 00130 void CmtDeviceMode::setPeriodAndSkipFactor(uint16_t period, uint16_t skip) 00131 { 00132 m_sampleFrequency = (uint16_t) floor((115200.0 / ((1.0 + (double) skip) * (double) period))+0.5); 00133 } 00134 00135 ////////////////////////////////////////////////////////////////////////////////////////// 00136 // Compute sample frequency from the period and skip factor. 00137 bool CmtDeviceMode::operator == (const CmtDeviceMode& dev) const 00138 { 00139 return m_outputMode == dev.m_outputMode && m_outputSettings == dev.m_outputSettings && m_sampleFrequency == dev.m_sampleFrequency; 00140 } 00141 00142 ////////////////////////////////////////////////////////////////////////////////////////// 00143 // Return the real sample frequency in Hz 00144 double CmtDeviceMode2::getRealSampleFrequency(void) const 00145 { 00146 if (m_skip != 0xFFFF) 00147 return (115200.0 / ((1.0 + (double) m_skip) * (double) m_period)); 00148 else 00149 return (115200.0 / ((double) m_period)); 00150 } 00151 00152 ////////////////////////////////////////////////////////////////////////////////////////// 00153 // Return the sample frequency in Hz 00154 uint16_t CmtDeviceMode2::getSampleFrequency(void) const 00155 { 00156 if (m_skip != 0xFFFF) 00157 return (uint16_t) floor((115200.0 / ((1.0 + (double) m_skip) * (double) m_period))+0.5); 00158 else 00159 return (uint16_t) floor((115200.0 / ((double) m_period))+0.5); 00160 } 00161 00162 void CmtDeviceMode2::setSampleFrequency(uint16_t frequency) 00163 { 00164 if (frequency == 0) 00165 { 00166 m_period = 0; 00167 m_skip = 0; 00168 return; 00169 } 00170 if (frequency >= 512) 00171 { 00172 m_period = 225; 00173 m_skip = 0; 00174 return; 00175 } 00176 00177 int32_t freq, sf = frequency; 00178 00179 // first try the simple ones 00180 m_skip = 0; 00181 freq = sf; 00182 while (freq < 100) 00183 { 00184 ++m_skip; 00185 freq += sf; 00186 } 00187 00188 m_period = (uint16_t) (115200 / freq); 00189 } 00190 00191 ////////////////////////////////////////////////////////////////////////////////////////// 00192 // Compute sample frequency from the period and skip factor. 00193 bool CmtDeviceMode2::operator == (const CmtDeviceMode2& dev) const 00194 { 00195 return m_outputMode == dev.m_outputMode && m_outputSettings == dev.m_outputSettings && m_period == dev.m_period && m_skip == dev.m_skip; 00196 } 00197 00198 ////////////////////////////////////////////////////////////////////////////////////////// 00199 // Common part of a data request function 00200 #define DO_DATA_REQUEST_BID(req,bid)\ 00201 Message snd(req,0);\ 00202 Message rcv;\ 00203 if (bid == CMT_BID_INVALID || bid == CMT_BID_BROADCAST)\ 00204 return (m_lastResult = XRV_INVALIDID);\ 00205 if (!m_readFromFile)\ 00206 {\ 00207 snd.setBusId(bid);\ 00208 m_serial.writeMessage(&snd);\ 00209 if ((m_lastResult = m_serial.waitForMessage(&rcv,req+1,0,true)) != XRV_OK)\ 00210 return m_lastResult;\ 00211 if (m_logging)\ 00212 m_logFile.writeMessage(&rcv);\ 00213 if (rcv.getMessageId() == CMT_MID_ERROR)\ 00214 { m_lastHwErrorDeviceId = m_config.m_masterDeviceId;\ 00215 if (rcv.getDataSize() >= 2)\ 00216 {\ 00217 uint8_t biddy = rcv.getDataByte(1);\ 00218 getDeviceId(biddy,m_lastHwErrorDeviceId);\ 00219 }\ 00220 return m_lastResult = m_lastHwError = (XsensResultValue) rcv.getDataByte();\ 00221 }\ 00222 }\ 00223 else\ 00224 while (1)\ 00225 {\ 00226 if ((m_lastResult = m_logFile.readMessage(&rcv,req+1)) != XRV_OK)\ 00227 return m_lastResult;\ 00228 if (rcv.getBusId() == bid || (rcv.getBusId() == 1 && bid == CMT_BID_MASTER))\ 00229 break;\ 00230 } 00231 00232 #define DO_DATA_REQUEST(req)\ 00233 uint8_t bid = getBusIdInternal(deviceId);\ 00234 DO_DATA_REQUEST_BID(req,bid); 00235 00236 ////////////////////////////////////////////////////////////////////////////////////////// 00237 // Common part of a serial data set function 00238 #define DO_DATA_SET_BID(req,size,type,data,bid)\ 00239 Message snd(req,size);\ 00240 Message rcv;\ 00241 snd.setData ## type (data);\ 00242 if (bid == CMT_BID_BROADCAST)\ 00243 {\ 00244 for (uint8_t i=0;i<m_config.m_numberOfDevices;++i)\ 00245 {\ 00246 snd.setBusId(i+1);\ 00247 m_serial.writeMessage(&snd);\ 00248 m_lastResult = m_serial.waitForMessage(&rcv,req+1,0,true);\ 00249 if (m_lastResult != XRV_OK)\ 00250 return m_lastResult;\ 00251 if (m_logging)\ 00252 m_logFile.writeMessage(&rcv);\ 00253 if (rcv.getMessageId() == CMT_MID_ERROR)\ 00254 { m_lastHwErrorDeviceId = m_config.m_masterDeviceId;\ 00255 if (rcv.getDataSize() >= 2)\ 00256 {\ 00257 uint8_t biddy = rcv.getDataByte(1);\ 00258 getDeviceId(biddy,m_lastHwErrorDeviceId);\ 00259 }\ 00260 return m_lastResult = m_lastHwError = (XsensResultValue) rcv.getDataByte();\ 00261 }\ 00262 }\ 00263 } else {\ 00264 snd.setBusId(bid);\ 00265 m_serial.writeMessage(&snd);\ 00266 m_lastResult = m_serial.waitForMessage(&rcv,req+1,0,true);\ 00267 if (m_lastResult != XRV_OK)\ 00268 return m_lastResult;\ 00269 if (m_logging)\ 00270 m_logFile.writeMessage(&rcv);\ 00271 if (rcv.getMessageId() == CMT_MID_ERROR)\ 00272 { m_lastHwErrorDeviceId = m_config.m_masterDeviceId;\ 00273 if (rcv.getDataSize() >= 2)\ 00274 {\ 00275 uint8_t biddy = rcv.getDataByte(1);\ 00276 getDeviceId(biddy,m_lastHwErrorDeviceId);\ 00277 }\ 00278 return m_lastResult = m_lastHwError = (XsensResultValue) rcv.getDataByte();\ 00279 }\ 00280 } 00281 00282 #define DO_DATA_SET(req,size,type,data)\ 00283 uint8_t bid = getBusIdInternal(deviceId);\ 00284 if (bid == CMT_BID_INVALID)\ 00285 return (m_lastResult = XRV_INVALIDID);\ 00286 DO_DATA_SET_BID(req,size,type,data,bid); 00287 00288 #define HANDLE_ERR_RESULT\ 00289 if (rcv.getMessageId() == CMT_MID_ERROR)\ 00290 {\ 00291 m_lastHwErrorDeviceId = m_config.m_masterDeviceId;\ 00292 if (rcv.getDataSize() >= 2)\ 00293 {\ 00294 uint8_t biddy = rcv.getDataByte(1);\ 00295 getDeviceId(biddy,m_lastHwErrorDeviceId);\ 00296 }\ 00297 return m_lastResult = m_lastHwError = (XsensResultValue) rcv.getDataByte(0);\ 00298 } 00299 00300 00301 ////////////////////////////////////////////////////////////////////////////////////////// 00302 ///////////////////////////////////////// Cmt3 ///////////////////////////////////////// 00303 ////////////////////////////////////////////////////////////////////////////////////////// 00304 00305 namespace xsens { 00306 00307 ////////////////////////////////////////////////////////////////////////////////////////// 00308 // Default constructor, initializes all members to their default values. 00309 Cmt3::Cmt3() 00310 { 00311 m_lastResult = XRV_OK; 00312 m_rtcInitialized = false; 00313 m_useRtc = true; 00314 m_measuring = false; 00315 m_timeoutConf = CMT3_DEFAULT_TIMEOUT_CONF; 00316 m_timeoutMeas = CMT3_DEFAULT_TIMEOUT_MEAS; 00317 m_gotoConfigTries = CMT_GOTO_CONFIG_TRIES; 00318 m_readFromFile = false; 00319 //m_sampleFrequency = 100.0; 00320 m_period = CMT_DEFAULT_PERIOD; 00321 m_skip = CMT_DEFAULT_SKIP; 00322 memset(m_eMtsData,0,sizeof(m_eMtsData)); 00323 memset(&m_config,0,sizeof(m_config)); 00324 m_logging = false; 00325 00326 clearHwError(); 00327 } 00328 00329 ////////////////////////////////////////////////////////////////////////////////////////// 00330 // Destructor, de-initializes, frees memory allocated for buffers, etc. 00331 Cmt3::~Cmt3() 00332 { 00333 m_serial.close(); 00334 m_logFile.close(); 00335 for (uint32_t i = 0; i < CMT_MAX_DEVICES_PER_PORT; ++i) 00336 { 00337 CHKFREENUL(m_eMtsData[i]); 00338 } 00339 } 00340 00341 ////////////////////////////////////////////////////////////////////////////////////////// 00342 // Close the serial communication port. 00343 XsensResultValue Cmt3::closePort(bool gotoConfigFirst) 00344 { 00345 CMT3LOG(__FUNCTION__ " closePort\n"); 00346 CMT3EXITLOG; 00347 00348 if (m_measuring && gotoConfigFirst) 00349 gotoConfig(); 00350 CMT3LOG(__FUNCTION__ " Closing L2 port\n"); 00351 m_serial.close(); 00352 m_measuring = false; 00353 if (m_logFile.isOpen()) 00354 { 00355 m_readFromFile = true; 00356 m_logging = false; 00357 } 00358 return m_lastResult = XRV_OK; 00359 } 00360 00361 ////////////////////////////////////////////////////////////////////////////////////////// 00362 void Cmt3::fillRtc(Packet* pack) 00363 { 00364 #if defined(_DEBUG) || defined(_LOG_ALWAYS) 00365 TimeStamp rt = 0; 00366 #endif 00367 00368 if (!m_rtcInitialized) 00369 { 00370 m_rtcStart = pack->m_toa; 00371 m_rtcLastSc = pack->getSampleCounter(); 00372 m_rtcCount = m_rtcLastSc; 00373 #ifdef _CORRECT_FOR_CLOCK_MISMATCH 00374 m_lastToaTouch = m_rtcLastSc; 00375 #endif 00376 CmtDeviceMode2 mode; 00377 mode.m_period = m_period; 00378 mode.m_skip = m_skip; 00379 m_rtcMsPerSample = 1000.0 / mode.getRealSampleFrequency(); 00380 pack->m_rtc = m_rtcStart; 00381 m_rtcInitialized = true; 00382 } 00383 else 00384 { 00385 CmtMtTimeStamp sc = pack->getSampleCounter(); 00386 CmtMtTimeStamp scdiff = sc - m_rtcLastSc; 00387 m_rtcLastSc = sc; 00388 m_rtcCount += scdiff; 00389 pack->m_rtc = m_rtcStart + (TimeStamp) floor(m_rtcMsPerSample * (double) m_rtcCount + 0.5); 00390 #ifdef _CORRECT_FOR_CLOCK_MISMATCH 00391 #if defined(_DEBUG) || defined(_LOG_ALWAYS) 00392 rt = pack->m_rtc; 00393 #endif 00394 // detect if arrival times are lower than expected 00395 // if so, we update the start time to correct for this 00396 if (pack->m_toa < pack->m_rtc) 00397 { 00398 m_lastToaTouch = m_rtcCount; 00399 // adjust start time to match new, earlier TOA 00400 TimeStamp diff = pack->m_rtc - pack->m_toa; 00401 00402 m_rtcStart -= diff; 00403 pack->m_rtc = pack->m_toa; 00404 } 00405 else if (pack->m_toa == pack->m_rtc) 00406 m_lastToaTouch = m_rtcCount; 00407 else if (((m_rtcCount-m_lastToaTouch) & 127) == 0) 00408 ++m_rtcStart; // we adjust the start time upwards by max 1ms per 128 samples 00409 #endif 00410 } 00411 //CMT3LOG(__FUNCTION__ " rtcStart: %I64u rtcPack: %I64u toa: %I64u\n",m_rtcStart,pack->m_rtc,pack->m_toa); 00412 // CMT3LOG("%I64u %I64u %I64u %I64u 101010101 %u\n",m_rtcStart,rt,pack->m_toa,pack->m_rtc,(long) this); 00413 } 00414 00415 #if 0 00416 obsolete: 00417 ////////////////////////////////////////////////////////////////////////////////////////// 00418 // Get the state (enabled/disabled) of the AMD algorithm 00419 XsensResultValue Cmt3::getAmdState(bool& state, const CmtDeviceId deviceId) 00420 { 00421 CMT3LOG("L3: getAmdState %08x\n",deviceId); 00422 CMT3EXITLOG; 00423 00424 DO_DATA_REQUEST(CMT_MID_REQAMD); 00425 state = (rcv.getDataShort() != 0); 00426 return m_lastResult = XRV_OK; 00427 } 00428 #endif 00429 00430 ////////////////////////////////////////////////////////////////////////////////////////// 00431 // Get the XM batery level 00432 XsensResultValue Cmt3::getBatteryLevel(uint8_t& level) 00433 { 00434 CMT3LOG(__FUNCTION__ "\n"); 00435 CMT3EXITLOG; 00436 00437 DO_DATA_REQUEST_BID(CMT_MID_REQBATLEVEL,CMT_BID_MASTER); 00438 level = rcv.getDataByte(); 00439 return m_lastResult = XRV_OK; 00440 } 00441 00442 ////////////////////////////////////////////////////////////////////////////////////////// 00443 // Get the baudrate that is currently being used by the port 00444 XsensResultValue Cmt3::getBaudrate(uint32_t& baudrate) 00445 { 00446 CMT3LOG(__FUNCTION__ "\n"); 00447 CMT3EXITLOG; 00448 00449 if (!m_serial.isOpen()) 00450 return m_lastResult = XRV_NOPORTOPEN; 00451 baudrate = m_baudrate; 00452 return m_lastResult = XRV_OK; 00453 } 00454 00455 ////////////////////////////////////////////////////////////////////////////////////////// 00456 // Get the state of the bluetooth communication, on (true) or off (false) 00457 XsensResultValue Cmt3::getBluetoothState(bool& enabled) 00458 { 00459 CMT3LOG(__FUNCTION__ "\n"); 00460 CMT3EXITLOG; 00461 00462 DO_DATA_REQUEST_BID(CMT_MID_REQBTDISABLE,CMT_BID_MASTER); 00463 enabled = (rcv.getDataByte() == 0); // invert the result as it is a disable field 00464 return m_lastResult = XRV_OK; 00465 } 00466 00467 ////////////////////////////////////////////////////////////////////////////////////////// 00468 // Retrieve the BusId of a device. 00469 XsensResultValue Cmt3::getBusId (uint8_t& busId, const CmtDeviceId deviceId) const 00470 { 00471 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 00472 CMT3EXITLOG; 00473 00474 if (deviceId == CMT_DID_MASTER || deviceId == m_config.m_masterDeviceId) 00475 { 00476 busId = CMT_BID_MASTER; 00477 return m_lastResult = XRV_OK; 00478 } 00479 00480 for (uint16_t i=0 ; i <= m_config.m_numberOfDevices ; ++i) 00481 if (m_config.m_deviceInfo[i].m_deviceId == deviceId) 00482 { 00483 busId = i+1; 00484 return m_lastResult = XRV_OK; 00485 } 00486 return m_lastResult = XRV_NOTFOUND; 00487 } 00488 00489 ////////////////////////////////////////////////////////////////////////////////////////// 00490 uint8_t Cmt3::getBusIdInternal(const CmtDeviceId devId) const 00491 { 00492 if (devId == CMT_DID_MASTER) 00493 return CMT_BID_MASTER; 00494 00495 if (devId == CMT_DID_BROADCAST) 00496 return CMT_BID_BROADCAST; 00497 00498 if (m_config.m_masterDeviceId == devId) 00499 return CMT_BID_MASTER; 00500 00501 for (uint16_t i = 0;i <= m_config.m_numberOfDevices;++i) 00502 { 00503 if (m_config.m_deviceInfo[i].m_deviceId == devId) 00504 return (uint8_t) (i+1); 00505 } 00506 return CMT_BID_INVALID; 00507 } 00508 00509 ////////////////////////////////////////////////////////////////////////////////////////// 00510 // Retrieve the XM bus power state. 00511 XsensResultValue Cmt3::getBusPowerState(bool& enabled) 00512 { 00513 CMT3LOG(__FUNCTION__ "\n"); 00514 CMT3EXITLOG; 00515 00516 DO_DATA_REQUEST_BID(CMT_MID_BUSPWR,CMT_BID_MASTER); 00517 enabled = (rcv.getDataShort() != 0); // invert the result as it is a disable field 00518 return m_lastResult = XRV_OK; 00519 } 00520 00521 ////////////////////////////////////////////////////////////////////////////////////////// 00522 Cmt2f* Cmt3::getCmt2f(void) 00523 { 00524 return &m_logFile; 00525 } 00526 00527 ////////////////////////////////////////////////////////////////////////////////////////// 00528 Cmt2s* Cmt3::getCmt2s(void) 00529 { 00530 return &m_serial; 00531 } 00532 00533 ////////////////////////////////////////////////////////////////////////////////////////// 00534 // Retrieve the complete device configuration of a device. 00535 XsensResultValue Cmt3::getConfiguration(CmtDeviceConfiguration& configuration) 00536 { 00537 CMT3LOG(__FUNCTION__ "\n"); 00538 CMT3EXITLOG; 00539 00540 if (!(m_serial.isOpen() || m_logFile.isOpen())) 00541 return m_lastResult = XRV_INVALIDOPERATION; 00542 00543 if (m_config.m_numberOfDevices > CMT_MAX_DEVICES_PER_PORT) 00544 return m_lastResult = XRV_CONFIGCHECKFAIL; 00545 00546 memcpy(&configuration,&m_config,sizeof(CmtDeviceConfiguration)); 00547 00548 if (m_logging) 00549 { 00550 // fake the message receipt 00551 Message msg(CMT_MID_CONFIGURATION,98 + CMT_CONF_BLOCKLEN*m_config.m_numberOfDevices); 00552 msg.setBusId(CMT_BID_MASTER); 00553 00554 msg.setDataLong(m_config.m_masterDeviceId, 0); 00555 msg.setDataShort(m_config.m_samplingPeriod, 4); 00556 msg.setDataShort(m_config.m_outputSkipFactor, 6); 00557 msg.setDataShort(m_config.m_syncinMode, 8); 00558 msg.setDataShort(m_config.m_syncinSkipFactor, 10); 00559 msg.setDataLong(m_config.m_syncinOffset, 12); 00560 memcpy(msg.getDataBuffer(16), m_config.m_date,8); 00561 memcpy(msg.getDataBuffer(24), m_config.m_time, 8); 00562 memcpy(msg.getDataBuffer(32), m_config.m_reservedForHost,32); 00563 memcpy(msg.getDataBuffer(64), m_config.m_reservedForClient,32); 00564 msg.setDataShort(m_config.m_numberOfDevices, 96); 00565 00566 for (uint16_t i = 0; i < m_config.m_numberOfDevices; ++i) 00567 { 00568 msg.setDataLong(m_config.m_deviceInfo[i].m_deviceId, 98+i*20); 00569 msg.setDataShort(m_config.m_deviceInfo[i].m_dataLength, 102+i*20); 00570 msg.setDataShort(m_config.m_deviceInfo[i].m_outputMode, 104+i*20); 00571 msg.setDataLong(m_config.m_deviceInfo[i].m_outputSettings, 106+i*20); 00572 msg.setDataShort(m_config.m_deviceInfo[i].m_currentScenario, 110+i*20); 00573 msg.setDataByte(m_config.m_deviceInfo[i].m_fwRevMajor, 112+i*20); 00574 msg.setDataByte(m_config.m_deviceInfo[i].m_fwRevMinor, 113+i*20); 00575 msg.setDataByte(m_config.m_deviceInfo[i].m_fwRevRevision, 114+i*20); 00576 msg.setDataByte(m_config.m_deviceInfo[i].m_filterType, 115+i*20); 00577 msg.setDataByte(m_config.m_deviceInfo[i].m_filterMajor, 116+i*20); 00578 msg.setDataByte(m_config.m_deviceInfo[i].m_filterMinor, 117+i*20); 00579 } 00580 00581 msg.recomputeChecksum(); 00582 00583 writeMessageToLogFile(msg); 00584 } 00585 return m_lastResult = XRV_OK; 00586 } 00587 00588 ////////////////////////////////////////////////////////////////////////////////////////// 00589 // Retrieve the number of bytes that are in a data message as sent by the device. 00590 XsensResultValue Cmt3::getDataLength(uint32_t& length, const CmtDeviceId deviceId) 00591 { 00592 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 00593 CMT3EXITLOG; 00594 00595 DO_DATA_REQUEST(CMT_MID_REQDATALENGTH); 00596 length = rcv.getDataShort(); // the sensor returns this value as a int16_t 00597 return m_lastResult = XRV_OK; 00598 } 00599 00600 ////////////////////////////////////////////////////////////////////////////////////////// 00601 // Return the number of connected devices. Returns 0 if not connected. 00602 uint32_t Cmt3::getDeviceCount (void) const 00603 { 00604 CMT3LOG(__FUNCTION__ "\n"); 00605 if (m_serial.isOpen() || m_logFile.isOpen()) 00606 { 00607 if (isXm()) 00608 return m_config.m_numberOfDevices + 1; 00609 else 00610 return m_config.m_numberOfDevices; 00611 } 00612 return 0; 00613 } 00614 00615 ////////////////////////////////////////////////////////////////////////////////////////// 00616 // Retrieve the CmtDeviceId of the device at the given BusId 00617 XsensResultValue Cmt3::getDeviceId(const uint8_t busId, CmtDeviceId& deviceId) const 00618 { 00619 CMT3LOG(__FUNCTION__ " %u\n",(uint32_t) busId); 00620 CMT3EXITLOG; 00621 00622 if (busId == CMT_BID_MASTER || busId == 0) 00623 deviceId = m_config.m_masterDeviceId; 00624 else 00625 { 00626 if (busId > m_config.m_numberOfDevices) 00627 return m_lastResult = XRV_INVALIDID; 00628 deviceId = m_config.m_deviceInfo[busId-1].m_deviceId; 00629 } 00630 return m_lastResult = XRV_OK; 00631 } 00632 00633 ////////////////////////////////////////////////////////////////////////////////////////// 00634 // Retrieve the complete device output mode of a device. 00635 XsensResultValue Cmt3::getDeviceMode(CmtDeviceMode& mode, const CmtDeviceId deviceId) 00636 { 00637 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 00638 CMT3EXITLOG; 00639 00640 CmtDeviceMode2 mode2; 00641 XsensResultValue rv; 00642 rv = getDeviceMode2(mode2, deviceId); 00643 if (rv == XRV_OK) { 00644 mode.m_outputMode = mode2.m_outputMode; 00645 mode.m_outputSettings = mode2.m_outputSettings; 00646 mode.m_sampleFrequency = mode2.getSampleFrequency(); 00647 } 00648 return rv; 00649 } 00650 00651 ////////////////////////////////////////////////////////////////////////////////////////// 00652 // Retrieve the complete device output mode of a device. 00653 XsensResultValue Cmt3::getDeviceMode2(CmtDeviceMode2& mode, const CmtDeviceId deviceId) 00654 { 00655 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 00656 CMT3EXITLOG; 00657 00658 uint8_t bid = getBusIdInternal(deviceId); 00659 if (bid == CMT_BID_INVALID) 00660 return m_lastResult = XRV_INVALIDID; 00661 if (bid == 0) 00662 return m_lastResult = XRV_INVALIDID; 00663 if (bid == CMT_BID_MASTER) 00664 bid = 1; 00665 00666 mode.m_period = m_period; 00667 mode.m_skip = m_skip; 00668 //mode.m_sampleFrequency = (uint16_t) floor(m_sampleFrequency+0.5); 00669 mode.m_outputMode = m_config.m_deviceInfo[bid-1].m_outputMode; 00670 mode.m_outputSettings = m_config.m_deviceInfo[bid-1].m_outputSettings; 00671 00672 return m_lastResult = XRV_OK; 00673 } 00674 00675 ////////////////////////////////////////////////////////////////////////////////////////// 00676 // Retrieve the eMts data of the specified sensor(s) 00677 #define _XM_SMALL_PACKETS_EMTS 0 00678 XsensResultValue Cmt3::getEMtsData(void* buffer, const CmtDeviceId deviceId) 00679 { 00680 CMT3LOG(__FUNCTION__ " %p %08x\n",buffer,deviceId); 00681 CMT3EXITLOG; 00682 00683 uint8_t bid = getBusIdInternal(deviceId); 00684 if (bid == CMT_BID_INVALID) 00685 return m_lastResult = XRV_INVALIDID; 00686 if (!m_readFromFile && !m_serial.isOpen()) 00687 return m_lastResult = XRV_NOPORTOPEN; 00688 if (m_readFromFile && !m_logFile.isOpen()) 00689 return m_lastResult = XRV_NOFILEOPEN; 00690 if (buffer == NULL) 00691 return m_lastResult = XRV_NULLPTR; 00692 00693 if (bid == CMT_BID_BROADCAST) 00694 { 00695 memset(buffer,0,m_config.m_numberOfDevices * CMT_EMTS_SIZE); 00696 uint8_t* buf = (uint8_t*) buffer; 00697 // loop over devices and request emts data for all of them 00698 for (uint32_t dev=0; dev < m_config.m_numberOfDevices; ++dev) 00699 if (getEMtsData(buf+dev*CMT_EMTS_SIZE,m_config.m_deviceInfo[dev].m_deviceId) != XRV_OK) 00700 return m_lastResult; 00701 //CMT3LOG("L3: getEMtsData (%08x) returns %d\n",deviceId,(int32_t)m_lastResult); 00702 return m_lastResult; 00703 } 00704 00705 uint8_t dataIndex; 00706 00707 if (isXm()) 00708 { 00709 if (bid == CMT_BID_MASTER) 00710 { 00711 //CMT3LOG("L3: getEMtsData (%08x) returns XRV_INVALIDID\n",deviceId); 00712 return m_lastResult = XRV_INVALIDID; 00713 } 00714 dataIndex = bid-1; 00715 } 00716 else 00717 dataIndex = 0; // when we have a single MT, we should use bank 0 00718 00719 if (m_eMtsData[dataIndex] == NULL) 00720 { 00721 m_eMtsData[dataIndex] = malloc(CMT_EMTS_SIZE); 00722 00723 // Xbus requires small data packets 00724 #if _XM_SMALL_PACKETS_EMTS 00725 if (isXm()) 00726 { 00727 Message msg(CMT_MID_REQEMTS,3); 00728 Message rcv; 00729 uint8_t* tme = (uint8_t*) m_eMtsData[dataIndex]; 00730 memset(tme,0,CMT_EMTS_SIZE); // clear eMTS data 00731 msg.setBusId(bid); 00732 msg.setDataByte(0,0); // read bank 0 00733 uint16_t emtPos = 0; 00734 for (uint8_t page=0;page < 4;++page) // read all 4 pages, one at a time 00735 { 00736 msg.setDataByte(page,1); 00737 for (uint8_t part=0;part < 4;++part, ++emtPos) 00738 { 00739 if (!m_readFromFile) 00740 { 00741 msg.setDataByte(part,2); 00742 m_serial.writeMessage(&msg); 00743 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_EMTSDATA,0,false); 00744 } 00745 else 00746 m_lastResult = m_logFile.readMessage(&rcv,CMT_MID_EMTSDATA); 00747 00748 if (m_lastResult != XRV_OK) 00749 { 00750 FREENUL(m_eMtsData[dataIndex]); 00751 //CMT3LOG("L3: getEMtsData (%08x) returns %d\n",deviceId,(int32_t)m_lastResult); 00752 return m_lastResult; 00753 } 00754 if (!m_readFromFile && m_logging) 00755 m_logFile.writeMessage(&rcv); 00756 if (rcv.getMessageId() == CMT_MID_ERROR) 00757 { 00758 m_lastHwErrorDeviceId = m_config.m_masterDeviceId; 00759 if (rcv.getDataSize() >= 2) 00760 { 00761 uint8_t biddy = rcv.getDataByte(1); 00762 getDeviceId(biddy,m_lastHwErrorDeviceId); 00763 } 00764 m_lastResult = m_lastHwError = (XsensResultValue) rcv.getDataByte(0); 00765 FREENUL(m_eMtsData[dataIndex]); 00766 //CMT3LOG("L3: getEMtsData (%08x) returns %d\n",deviceId,(int32_t)m_lastResult); 00767 return m_lastResult; 00768 } 00769 00770 memcpy(tme+(emtPos*66),rcv.getDataBuffer(),66); 00771 } 00772 } 00773 } // if (isXm()) 00774 else // single MT, ask in one packet 00775 { 00776 #endif 00777 Message msg(CMT_MID_REQEMTS,2); 00778 Message rcv; 00779 memset(m_eMtsData[dataIndex],0,CMT_EMTS_SIZE); // clear eMTS data 00780 msg.setBusId(bid); 00781 msg.setDataByte(0,0); // read bank 0 00782 msg.setDataByte(255,1); // read all pages 00783 00784 if (!m_readFromFile) 00785 { 00786 m_serial.writeMessage(&msg); 00787 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_EMTSDATA,0,false); 00788 } 00789 else 00790 m_lastResult = m_logFile.readMessage(&rcv,CMT_MID_EMTSDATA); 00791 if (m_lastResult != XRV_OK) 00792 { 00793 FREENUL(m_eMtsData[dataIndex]); 00794 //CMT3LOG("L3: getEMtsData (%08x) returns %d\n",deviceId,(int32_t)m_lastResult); 00795 return m_lastResult; 00796 } 00797 if (!m_readFromFile && m_logging) 00798 m_logFile.writeMessage(&rcv); 00799 if (rcv.getMessageId() == CMT_MID_ERROR) 00800 { 00801 m_lastHwErrorDeviceId = m_config.m_masterDeviceId; 00802 if (rcv.getDataSize() >= 2) 00803 { 00804 uint8_t biddy = rcv.getDataByte(1); 00805 getDeviceId(biddy,m_lastHwErrorDeviceId); 00806 } 00807 m_lastResult = m_lastHwError = (XsensResultValue) rcv.getDataByte(0); 00808 FREENUL(m_eMtsData[dataIndex]); 00809 //CMT3LOG("L3: getEMtsData (%08x) returns %d\n",deviceId,(int32_t)m_lastResult); 00810 return m_lastResult; 00811 } 00812 00813 memcpy(m_eMtsData[dataIndex],rcv.getDataBuffer(),rcv.getDataSize());//CMT_EMTS_SIZE); 00814 #if _XM_SMALL_PACKETS_EMTS 00815 } 00816 #endif 00817 } else if (m_logging) 00818 { 00819 // fake the message receipt 00820 Message msg(CMT_MID_EMTSDATA,CMT_EMTS_SIZE); 00821 msg.setBusId(bid); 00822 msg.setDataBuffer((const uint8_t*) m_eMtsData[dataIndex],0,CMT_EMTS_SIZE); 00823 writeMessageToLogFile(msg); 00824 } 00825 00826 memcpy(buffer,m_eMtsData[dataIndex],CMT_EMTS_SIZE); 00827 //CMT3LOG("L3: getEMtsData (%08x) returns XRV_OK\n",deviceId); 00828 return m_lastResult = XRV_OK; 00829 } 00830 00831 ////////////////////////////////////////////////////////////////////////////////////////// 00832 // Retrieve the error mode 00833 XsensResultValue Cmt3::getErrorMode(uint16_t& mode, const CmtDeviceId deviceId) 00834 { 00835 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 00836 CMT3EXITLOG; 00837 00838 if (isXm()) 00839 { 00840 DO_DATA_REQUEST_BID(CMT_MID_REQXMERRORMODE,CMT_BID_MASTER); 00841 mode = rcv.getDataShort(); 00842 } 00843 else 00844 { 00845 DO_DATA_REQUEST(CMT_MID_REQERRORMODE); 00846 mode = rcv.getDataShort(); 00847 } 00848 return m_lastResult = XRV_OK; 00849 } 00850 00851 #if 0 00852 obsolete: 00853 ////////////////////////////////////////////////////////////////////////////////////////// 00854 // Retrieve the filter settings of a device. 00855 XsensResultValue Cmt3::getFilterSettings(CmtFilterSettings& settings, const CmtDeviceId deviceId) 00856 { 00857 Message snd; 00858 Message rcv; 00859 uint8_t bid = getBusIdInternal(deviceId); 00860 if (bid == CMT_BID_INVALID) 00861 return (m_lastResult = XRV_INVALIDID); 00862 00863 bool xm = isXm(); 00864 00865 if (xm && deviceId == m_config.m_masterDeviceId) 00866 return m_lastResult = XRV_INVALIDOPERATION; 00867 00868 if (!xm) 00869 bid = CMT_BID_MASTER; 00870 00871 // first setting: gain 00872 snd.setBusId(bid); 00873 snd.setDataByte(0); 00874 snd.setMessageId(CMT_MID_REQFILTERSETTINGS); 00875 m_serial.writeMessage(&snd); 00876 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQFILTERSETTINGSACK,0,true); 00877 if (m_lastResult != XRV_OK) 00878 return m_lastResult; 00879 if (m_logging) 00880 m_logFile.writeMessage(&rcv); 00881 HANDLE_ERR_RESULT; 00882 settings.m_gain = rcv.getDataFloat(1); 00883 00884 // second setting: weighting 00885 snd.setBusId(bid); 00886 snd.setDataByte(1); 00887 snd.setMessageId(CMT_MID_REQFILTERSETTINGS); 00888 m_serial.writeMessage(&snd); 00889 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQFILTERSETTINGSACK,0,true); 00890 if (m_lastResult != XRV_OK) 00891 return m_lastResult; 00892 if (m_logging) 00893 m_logFile.writeMessage(&rcv); 00894 HANDLE_ERR_RESULT; 00895 settings.m_weighting = rcv.getDataFloat(1); 00896 00897 return m_lastResult = XRV_OK; 00898 } 00899 #endif 00900 00901 ////////////////////////////////////////////////////////////////////////////////////////// 00902 // Retrieve the firmware revision of a device. 00903 XsensResultValue Cmt3::getFirmwareRevision(CmtVersion& revision, const CmtDeviceId deviceId) 00904 { 00905 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 00906 CMT3EXITLOG; 00907 00908 DO_DATA_REQUEST(CMT_MID_REQFWREV); 00909 00910 revision.m_major = rcv.getDataByte(0); 00911 revision.m_minor = rcv.getDataByte(1); 00912 revision.m_revision = rcv.getDataByte(2); 00913 00914 return m_lastResult = XRV_OK; 00915 } 00916 00917 ////////////////////////////////////////////////////////////////////////////////////////// 00918 // Retrieve the heading offset of a device. The range is -pi to +pi. 00919 XsensResultValue Cmt3::getHeading(double& heading, const CmtDeviceId deviceId) 00920 { 00921 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 00922 CMT3EXITLOG; 00923 00924 DO_DATA_REQUEST(CMT_MID_REQHEADING); 00925 heading = rcv.getDataFloat(); 00926 return m_lastResult = XRV_OK; 00927 } 00928 00929 ////////////////////////////////////////////////////////////////////////////////////////// 00930 // Retrieve the last stored position of the sensor 00931 XsensResultValue Cmt3::getLatLonAlt(CmtVector& lla, const CmtDeviceId deviceId) 00932 { 00933 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 00934 CMT3EXITLOG; 00935 00936 DO_DATA_REQUEST(CMT_MID_REQLATLONALT); 00937 lla.m_data[0] = rcv.getDataFloat(0); 00938 lla.m_data[1] = rcv.getDataFloat(4); 00939 lla.m_data[2] = rcv.getDataFloat(8); 00940 return m_lastResult = XRV_OK; 00941 } 00942 00943 ////////////////////////////////////////////////////////////////////////////////////////// 00944 // Retrieve the location ID of a device. The buffer should be at least 20 bytes. 00945 XsensResultValue Cmt3::getLocationId(uint16_t& locationId, const CmtDeviceId deviceId) 00946 { 00947 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 00948 CMT3EXITLOG; 00949 00950 DO_DATA_REQUEST(CMT_MID_REQLOCATIONID); 00951 locationId = rcv.getDataShort(); 00952 return m_lastResult = XRV_OK; 00953 } 00954 00955 ////////////////////////////////////////////////////////////////////////////////////////// 00956 // Retrieve the current log file read position 00957 XsensResultValue Cmt3::getLogFileReadPosition(CmtFilePos& pos) 00958 { 00959 CMT3LOG(__FUNCTION__ "\n"); 00960 CMT3EXITLOG; 00961 00962 if (m_logFile.isOpen()) 00963 { 00964 pos = m_logFile.getReadPosition(); 00965 return m_lastResult = XRV_OK; 00966 } 00967 pos = 0; 00968 return m_lastResult = XRV_NOFILEOPEN; 00969 } 00970 00971 ////////////////////////////////////////////////////////////////////////////////////////// 00972 // Retrieve the size of the log file 00973 XsensResultValue Cmt3::getLogFileSize(CmtFilePos& size) 00974 { 00975 CMT3LOG(__FUNCTION__ "\n"); 00976 CMT3EXITLOG; 00977 00978 if (m_logFile.isOpen()) 00979 { 00980 size = m_logFile.getFileSize(); 00981 return m_lastResult = XRV_OK; 00982 } 00983 size = 0; 00984 return m_lastResult = XRV_NOFILEOPEN; 00985 } 00986 00987 ////////////////////////////////////////////////////////////////////////////////////////// 00988 // Retrieve the name of the open log file or an empty string if no logfile is open 00989 XsensResultValue Cmt3::getLogFileName(char* filename) 00990 { 00991 CMT3LOG(__FUNCTION__ " (char) %p\n",filename); 00992 CMT3EXITLOG; 00993 00994 if (m_logFile.isOpen()) 00995 return m_lastResult = m_logFile.getName(filename); 00996 filename[0] = '\0'; 00997 return m_lastResult = XRV_NOFILEOPEN; 00998 } 00999 01000 ////////////////////////////////////////////////////////////////////////////////////////// 01001 // Retrieve the name of the open log file or an empty string if no logfile is open 01002 XsensResultValue Cmt3::getLogFileName(wchar_t* filename) 01003 { 01004 CMT3LOG(__FUNCTION__ " (wchar_t) %p\n",filename); 01005 CMT3EXITLOG; 01006 01007 if (m_logFile.isOpen()) 01008 return m_lastResult = m_logFile.getName(filename); 01009 filename[0] = L'\0'; 01010 return m_lastResult = XRV_NOFILEOPEN; 01011 } 01012 01013 ////////////////////////////////////////////////////////////////////////////////////////// 01014 // Return the magnetic declination. The range is -pi to +pi. 01015 XsensResultValue Cmt3::getMagneticDeclination(double& declination, const CmtDeviceId deviceId) 01016 { 01017 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 01018 CMT3EXITLOG; 01019 01020 DO_DATA_REQUEST(CMT_MID_REQMAGNETICDECLINATION); 01021 declination = rcv.getDataFloat(); 01022 return m_lastResult = XRV_OK; 01023 } 01024 01025 ////////////////////////////////////////////////////////////////////////////////////////// 01026 // Return the device Id of the first device (master) 01027 CmtDeviceId Cmt3::getMasterId(void) 01028 { 01029 CMT3LOG(__FUNCTION__ "\n"); 01030 01031 if (m_serial.isOpen() || m_logFile.isOpen()) 01032 return m_config.m_masterDeviceId; 01033 return 0; 01034 } 01035 01036 ////////////////////////////////////////////////////////////////////////////////////////// 01037 // Return the nr of connected MTs (excludes XMs) 01038 const uint16_t Cmt3::getMtCount(void) const 01039 { 01040 CMT3LOGDAT(__FUNCTION__ "\n"); 01041 01042 if (m_serial.isOpen() || m_logFile.isOpen()) 01043 return m_config.m_numberOfDevices; 01044 return 0; 01045 } 01046 01047 ////////////////////////////////////////////////////////////////////////////////////////// 01048 // Retrieve the CmtDeviceId of the MT device with the given index 01049 XsensResultValue Cmt3::getMtDeviceId (const uint8_t index, CmtDeviceId& deviceId) const 01050 { 01051 CMT3LOG(__FUNCTION__ " %u\n",(uint32_t) index); 01052 CMT3EXITLOG; 01053 01054 if (index >= m_config.m_numberOfDevices) 01055 return m_lastResult = XRV_INVALIDPARAM; 01056 deviceId = m_config.m_deviceInfo[index].m_deviceId; 01057 return m_lastResult = XRV_OK; 01058 } 01059 01060 XsensResultValue Cmt3::getObjectAlignmentMatrix(CmtMatrix& matrix, const CmtDeviceId deviceId) 01061 { 01062 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 01063 CMT3EXITLOG; 01064 01065 DO_DATA_REQUEST(CMT_MID_REQOBJECTALIGNMENT); 01066 matrix.m_data[0][0] = rcv.getDataFloat(0); 01067 matrix.m_data[0][1] = rcv.getDataFloat(4); 01068 matrix.m_data[0][2] = rcv.getDataFloat(8); 01069 matrix.m_data[1][0] = rcv.getDataFloat(12); 01070 matrix.m_data[1][1] = rcv.getDataFloat(16); 01071 matrix.m_data[1][2] = rcv.getDataFloat(20); 01072 matrix.m_data[2][0] = rcv.getDataFloat(24); 01073 matrix.m_data[2][1] = rcv.getDataFloat(28); 01074 matrix.m_data[2][2] = rcv.getDataFloat(32); 01075 return m_lastResult = XRV_OK; 01076 } 01077 01078 ////////////////////////////////////////////////////////////////////////////////////////// 01079 // Retrieve the port that the object is connected to. 01080 XsensResultValue Cmt3::getPortNr(uint16_t& port) const 01081 { 01082 CMT3LOG(__FUNCTION__ "\n"); 01083 CMT3EXITLOG; 01084 01085 return m_lastResult = m_serial.getPortNr(port); 01086 } 01087 01088 ////////////////////////////////////////////////////////////////////////////////////////// 01089 // Retrieve the processing flags of a device. 01090 XsensResultValue Cmt3::getProcessingFlags(uint16_t& processingFlags, const CmtDeviceId deviceId) 01091 { 01092 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 01093 CMT3EXITLOG; 01094 01095 DO_DATA_REQUEST(CMT_MID_REQPROCESSINGFLAGS); 01096 processingFlags = rcv.getDataShort(); 01097 return m_lastResult = XRV_OK; 01098 } 01099 01100 ////////////////////////////////////////////////////////////////////////////////////////// 01101 // Retrieve the product code of a device. The buffer should be at least 21 bytes. 01102 XsensResultValue Cmt3::getProductCode (char* productCode, const CmtDeviceId deviceId) 01103 { 01104 CMT3LOG(__FUNCTION__ " %p %08x\n",productCode,deviceId); 01105 CMT3EXITLOG; 01106 01107 DO_DATA_REQUEST(CMT_MID_REQPRODUCTCODE); 01108 01109 uint16_t len = rcv.getDataSize(); 01110 memcpy(productCode,rcv.getDataBuffer(),len); 01111 productCode[len] = '\0'; 01112 01113 return m_lastResult = XRV_OK; 01114 } 01115 01116 ////////////////////////////////////////////////////////////////////////////////////////// 01117 // Retrieve the sample frequency of the devices on the bus. 01118 uint16_t Cmt3::getSampleFrequency(void) 01119 { 01120 CMT3LOG(__FUNCTION__ "\n"); 01121 CmtDeviceMode2 mode; 01122 mode.m_period = m_period; 01123 mode.m_skip = m_skip; 01124 01125 return mode.getSampleFrequency(); 01126 } 01127 01128 ////////////////////////////////////////////////////////////////////////////////////////// 01129 // Get the baudrate that is reported for the serial connection 01130 XsensResultValue Cmt3::getSerialBaudrate(uint32_t& baudrate) 01131 { 01132 CMT3LOG(__FUNCTION__ "\n"); 01133 CMT3EXITLOG; 01134 01135 DO_DATA_REQUEST_BID(CMT_MID_REQBAUDRATE,CMT_BID_MASTER); 01136 switch (rcv.getDataByte()) 01137 { 01138 case CMT_BAUDCODE_4K8: 01139 baudrate = CMT_BAUD_RATE_4800; 01140 break; 01141 case CMT_BAUDCODE_9K6: 01142 baudrate = CMT_BAUD_RATE_9600; 01143 break; 01144 // case CMT_BAUDCODE_14K4: 01145 // baudrate = CMT_BAUD_RATE_14K4; 01146 // break; 01147 case CMT_BAUDCODE_19K2: 01148 baudrate = CMT_BAUD_RATE_19K2; 01149 break; 01150 // case CMT_BAUDCODE_28K8: 01151 // baudrate = CMT_BAUD_RATE_28K8; 01152 // break; 01153 case CMT_BAUDCODE_38K4: 01154 baudrate = CMT_BAUD_RATE_38K4; 01155 break; 01156 case CMT_BAUDCODE_57K6: 01157 baudrate = CMT_BAUD_RATE_57K6; 01158 break; 01159 // case CMT_BAUDCODE_76K8: 01160 // baudrate = CMT_BAUD_RATE_76K8; 01161 // break; 01162 case CMT_BAUDCODE_115K2: 01163 baudrate = CMT_BAUD_RATE_115K2; 01164 break; 01165 case CMT_BAUDCODE_230K4: 01166 baudrate = CMT_BAUD_RATE_230K4; 01167 break; 01168 case CMT_BAUDCODE_460K8: 01169 baudrate = CMT_BAUD_RATE_460K8; 01170 break; 01171 case CMT_BAUDCODE_921K6_ALT: 01172 case CMT_BAUDCODE_921K6: 01173 baudrate = CMT_BAUD_RATE_921K6; 01174 break; 01175 default: 01176 return m_lastResult = XRV_BAUDRATEINVALID; 01177 } 01178 return m_lastResult = XRV_OK; 01179 } 01180 01181 ////////////////////////////////////////////////////////////////////////////////////////// 01182 // Retrieve the inbound synchronization settings of a device. 01183 XsensResultValue Cmt3::getSyncInSettings(CmtSyncInSettings& settings) 01184 { 01185 CMT3LOG(__FUNCTION__ "\n"); 01186 CMT3EXITLOG; 01187 01188 Message snd(CMT_MID_REQSYNCINSETTINGS,1); 01189 Message rcv; 01190 01191 snd.setBusId(CMT_BID_MASTER); 01192 01193 snd.setDataByte(CMT_PARAM_SYNCIN_MODE); 01194 m_serial.writeMessage(&snd); 01195 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCINSETTINGSACK,0,true); 01196 if (m_lastResult != XRV_OK) 01197 return m_lastResult; 01198 if (m_logging) 01199 m_logFile.writeMessage(&rcv); 01200 HANDLE_ERR_RESULT; 01201 settings.m_mode = rcv.getDataShort(1); 01202 01203 snd.setDataByte(CMT_PARAM_SYNCIN_SKIPFACTOR); 01204 m_serial.writeMessage(&snd); 01205 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCINSETTINGSACK,0,true); 01206 if (m_lastResult != XRV_OK) 01207 return m_lastResult; 01208 if (m_logging) 01209 m_logFile.writeMessage(&rcv); 01210 HANDLE_ERR_RESULT; 01211 settings.m_skipFactor = rcv.getDataShort(1); 01212 01213 snd.setDataByte(CMT_PARAM_SYNCIN_OFFSET); 01214 m_serial.writeMessage(&snd); 01215 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCINSETTINGSACK,0,true); 01216 if (m_lastResult != XRV_OK) 01217 return m_lastResult; 01218 if (m_logging) 01219 m_logFile.writeMessage(&rcv); 01220 HANDLE_ERR_RESULT; 01221 settings.m_offset = rcv.getDataLong(1); 01222 01223 // convert the offset to ns 01224 settings.m_offset = (uint32_t) ((((double)settings.m_offset)*CMT_SYNC_CLOCK_TICKS_TO_NS)+0.5); 01225 01226 return m_lastResult = XRV_OK; 01227 } 01228 01229 ////////////////////////////////////////////////////////////////////////////////////////// 01230 // Retrieve the inbound synchronization mode of a device. 01231 XsensResultValue Cmt3::getSyncInMode(uint16_t& mode) 01232 { 01233 CMT3LOG(__FUNCTION__ "\n"); 01234 CMT3EXITLOG; 01235 01236 Message snd(CMT_MID_REQSYNCINSETTINGS,1); 01237 Message rcv; 01238 01239 snd.setBusId(CMT_BID_MASTER); 01240 01241 snd.setDataByte(CMT_PARAM_SYNCIN_MODE); 01242 m_serial.writeMessage(&snd); 01243 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCINSETTINGSACK,0,true); 01244 if (m_lastResult != XRV_OK) 01245 return m_lastResult; 01246 if (m_logging) 01247 m_logFile.writeMessage(&rcv); 01248 HANDLE_ERR_RESULT; 01249 mode = rcv.getDataShort(1); 01250 01251 return m_lastResult = XRV_OK; 01252 } 01253 01254 ////////////////////////////////////////////////////////////////////////////////////////// 01255 // Retrieve the inbound synchronization skip factor of a device. 01256 XsensResultValue Cmt3::getSyncInSkipFactor(uint16_t& skipFactor) 01257 { 01258 CMT3LOG(__FUNCTION__ "\n"); 01259 CMT3EXITLOG; 01260 01261 Message snd(CMT_MID_REQSYNCINSETTINGS,1); 01262 Message rcv; 01263 01264 snd.setBusId(CMT_BID_MASTER); 01265 01266 snd.setDataByte(CMT_PARAM_SYNCIN_SKIPFACTOR); 01267 m_serial.writeMessage(&snd); 01268 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCINSETTINGSACK,0,true); 01269 if (m_lastResult != XRV_OK) 01270 return m_lastResult; 01271 if (m_logging) 01272 m_logFile.writeMessage(&rcv); 01273 HANDLE_ERR_RESULT; 01274 skipFactor = rcv.getDataShort(1); 01275 01276 return m_lastResult = XRV_OK; 01277 } 01278 01279 ////////////////////////////////////////////////////////////////////////////////////////// 01280 // Retrieve the inbound synchronization offset of a device. 01281 XsensResultValue Cmt3::getSyncInOffset(uint32_t& offset) 01282 { 01283 CMT3LOG(__FUNCTION__ "\n"); 01284 CMT3EXITLOG; 01285 01286 Message snd(CMT_MID_REQSYNCINSETTINGS,1); 01287 Message rcv; 01288 01289 snd.setBusId(CMT_BID_MASTER); 01290 01291 snd.setDataByte(CMT_PARAM_SYNCIN_OFFSET); 01292 m_serial.writeMessage(&snd); 01293 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCINSETTINGSACK,0,true); 01294 if (m_lastResult != XRV_OK) 01295 return m_lastResult; 01296 if (m_logging) 01297 m_logFile.writeMessage(&rcv); 01298 HANDLE_ERR_RESULT; 01299 offset = rcv.getDataLong(1); 01300 01301 // convert the offset to ns 01302 offset = (uint32_t) ((((double)offset)*CMT_SYNC_CLOCK_TICKS_TO_NS)+0.5); 01303 01304 return m_lastResult = XRV_OK; 01305 } 01306 01307 ////////////////////////////////////////////////////////////////////////////////////////// 01308 // Get the synchronization mode of the XM 01309 XsensResultValue Cmt3::getSyncMode(uint8_t& mode) 01310 { 01311 CMT3LOG(__FUNCTION__ "\n"); 01312 CMT3EXITLOG; 01313 01314 DO_DATA_REQUEST_BID(CMT_MID_REQSYNCMODE,CMT_BID_MASTER); 01315 mode = rcv.getDataByte(); 01316 return m_lastResult = XRV_OK; 01317 } 01318 01319 ////////////////////////////////////////////////////////////////////////////////////////// 01320 // Retrieve the outbound synchronization settings of a device. 01321 XsensResultValue Cmt3::getSyncOutSettings(CmtSyncOutSettings& settings) 01322 { 01323 CMT3LOG(__FUNCTION__ "\n"); 01324 CMT3EXITLOG; 01325 01326 Message snd(CMT_MID_REQSYNCOUTSETTINGS,1); 01327 Message rcv; 01328 01329 snd.setBusId(CMT_BID_MASTER); 01330 01331 snd.setDataByte(CMT_PARAM_SYNCOUT_MODE); 01332 m_serial.writeMessage(&snd); 01333 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 01334 if (m_lastResult != XRV_OK) 01335 return m_lastResult; 01336 if (m_logging) 01337 m_logFile.writeMessage(&rcv); 01338 HANDLE_ERR_RESULT; 01339 settings.m_mode = rcv.getDataShort(1); 01340 01341 snd.setDataByte(CMT_PARAM_SYNCOUT_SKIPFACTOR); 01342 m_serial.writeMessage(&snd); 01343 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 01344 if (m_lastResult != XRV_OK) 01345 return m_lastResult; 01346 if (m_logging) 01347 m_logFile.writeMessage(&rcv); 01348 HANDLE_ERR_RESULT; 01349 settings.m_skipFactor = rcv.getDataShort(1); 01350 01351 snd.setDataByte(CMT_PARAM_SYNCOUT_OFFSET); 01352 m_serial.writeMessage(&snd); 01353 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 01354 if (m_lastResult != XRV_OK) 01355 return m_lastResult; 01356 if (m_logging) 01357 m_logFile.writeMessage(&rcv); 01358 HANDLE_ERR_RESULT; 01359 settings.m_offset = rcv.getDataLong(1); 01360 01361 snd.setDataByte(CMT_PARAM_SYNCOUT_PULSEWIDTH); 01362 m_serial.writeMessage(&snd); 01363 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 01364 if (m_lastResult != XRV_OK) 01365 return m_lastResult; 01366 if (m_logging) 01367 m_logFile.writeMessage(&rcv); 01368 HANDLE_ERR_RESULT; 01369 settings.m_pulseWidth = rcv.getDataLong(1); 01370 01371 // convert the offset and pulse width to ns 01372 settings.m_offset = (uint32_t) ((((double)settings.m_offset)*CMT_SYNC_CLOCK_TICKS_TO_NS)+0.5); 01373 settings.m_pulseWidth = (uint32_t) ((((double)settings.m_pulseWidth)*CMT_SYNC_CLOCK_TICKS_TO_NS)+0.5); 01374 01375 return m_lastResult = XRV_OK; 01376 } 01377 01378 ////////////////////////////////////////////////////////////////////////////////////////// 01379 // Retrieve the outbound synchronization mode of a device. 01380 XsensResultValue Cmt3::getSyncOutMode(uint16_t& mode) 01381 { 01382 CMT3LOG(__FUNCTION__ "\n"); 01383 CMT3EXITLOG; 01384 01385 Message snd(CMT_MID_REQSYNCOUTSETTINGS,1); 01386 Message rcv; 01387 01388 snd.setBusId(CMT_BID_MASTER); 01389 01390 snd.setDataByte(CMT_PARAM_SYNCOUT_MODE); 01391 m_serial.writeMessage(&snd); 01392 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 01393 if (m_lastResult != XRV_OK) 01394 return m_lastResult; 01395 if (m_logging) 01396 m_logFile.writeMessage(&rcv); 01397 HANDLE_ERR_RESULT; 01398 mode = rcv.getDataShort(1); 01399 01400 return m_lastResult = XRV_OK; 01401 } 01402 01403 ////////////////////////////////////////////////////////////////////////////////////////// 01404 // Retrieve the outbound synchronization pulse width of a device. 01405 XsensResultValue Cmt3::getSyncOutPulseWidth(uint32_t& pulseWidth) 01406 { 01407 CMT3LOG(__FUNCTION__ "\n"); 01408 CMT3EXITLOG; 01409 01410 Message snd(CMT_MID_REQSYNCOUTSETTINGS,1); 01411 Message rcv; 01412 01413 snd.setBusId(CMT_BID_MASTER); 01414 01415 snd.setDataByte(CMT_PARAM_SYNCOUT_PULSEWIDTH); 01416 m_serial.writeMessage(&snd); 01417 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 01418 if (m_lastResult != XRV_OK) 01419 return m_lastResult; 01420 if (m_logging) 01421 m_logFile.writeMessage(&rcv); 01422 HANDLE_ERR_RESULT; 01423 pulseWidth = rcv.getDataLong(1); 01424 01425 // convert the pulse width to ns 01426 pulseWidth = (uint32_t) ((((double)pulseWidth)*CMT_SYNC_CLOCK_TICKS_TO_NS)+0.5); 01427 01428 return m_lastResult = XRV_OK; 01429 } 01430 01431 ////////////////////////////////////////////////////////////////////////////////////////// 01432 // Retrieve the outbound synchronization skip factor of a device. 01433 XsensResultValue Cmt3::getSyncOutSkipFactor(uint16_t& skipFactor) 01434 { 01435 CMT3LOG(__FUNCTION__ "\n"); 01436 CMT3EXITLOG; 01437 01438 Message snd(CMT_MID_REQSYNCOUTSETTINGS,1); 01439 Message rcv; 01440 01441 snd.setBusId(CMT_BID_MASTER); 01442 01443 snd.setDataByte(CMT_PARAM_SYNCOUT_SKIPFACTOR); 01444 m_serial.writeMessage(&snd); 01445 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 01446 if (m_lastResult != XRV_OK) 01447 return m_lastResult; 01448 if (m_logging) 01449 m_logFile.writeMessage(&rcv); 01450 HANDLE_ERR_RESULT; 01451 skipFactor = rcv.getDataShort(1); 01452 01453 return m_lastResult = XRV_OK; 01454 } 01455 01456 ////////////////////////////////////////////////////////////////////////////////////////// 01457 // Retrieve the outbound synchronization offset of a device. 01458 XsensResultValue Cmt3::getSyncOutOffset(uint32_t& offset) 01459 { 01460 CMT3LOG(__FUNCTION__ "\n"); 01461 CMT3EXITLOG; 01462 01463 Message snd(CMT_MID_REQSYNCOUTSETTINGS,1); 01464 Message rcv; 01465 01466 snd.setBusId(CMT_BID_MASTER); 01467 01468 snd.setDataByte(CMT_PARAM_SYNCOUT_OFFSET); 01469 m_serial.writeMessage(&snd); 01470 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 01471 if (m_lastResult != XRV_OK) 01472 return m_lastResult; 01473 if (m_logging) 01474 m_logFile.writeMessage(&rcv); 01475 HANDLE_ERR_RESULT; 01476 offset = rcv.getDataLong(1); 01477 01478 // convert the offset to ns 01479 offset = (uint32_t) ((((double)offset)*CMT_SYNC_CLOCK_TICKS_TO_NS)+0.5); 01480 01481 return m_lastResult = XRV_OK; 01482 } 01483 01484 ////////////////////////////////////////////////////////////////////////////////////////// 01485 uint32_t Cmt3::getTimeoutConfig (void) const 01486 { 01487 return m_timeoutConf; 01488 } 01489 01490 ////////////////////////////////////////////////////////////////////////////////////////// 01491 uint32_t Cmt3::getTimeoutMeasurement (void) const 01492 { 01493 return m_timeoutMeas; 01494 } 01495 01496 ////////////////////////////////////////////////////////////////////////////////////////// 01497 // Retrieve the transmission delay 01498 XsensResultValue Cmt3::getTransmissionDelay(uint16_t& delay, const CmtDeviceId deviceId) 01499 { 01500 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 01501 CMT3EXITLOG; 01502 01503 DO_DATA_REQUEST(CMT_MID_REQTRANSMITDELAY); 01504 delay = rcv.getDataShort(); 01505 01506 return m_lastResult = XRV_OK; 01507 } 01508 01509 ////////////////////////////////////////////////////////////////////////////////////////// 01510 // Retrieve the UTC time of the last received sample 01511 XsensResultValue Cmt3::getUtcTime(CmtUtcTime& utc, const CmtDeviceId deviceId) 01512 { 01513 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 01514 CMT3EXITLOG; 01515 01516 DO_DATA_REQUEST(CMT_MID_REQUTCTIME); 01517 01518 utc.m_nano = rcv.getDataLong(0); 01519 utc.m_year = rcv.getDataShort(4); 01520 utc.m_month = rcv.getDataByte(6); 01521 utc.m_day = rcv.getDataByte(7); 01522 utc.m_hour = rcv.getDataByte(8); 01523 utc.m_minute= rcv.getDataByte(9); 01524 utc.m_second= rcv.getDataByte(10); 01525 utc.m_valid = rcv.getDataByte(11); 01526 01527 // if (utc.m_valid == 0) 01528 // return m_lastResult = XRV_INVALID_TIME; 01529 01530 return m_lastResult = XRV_OK; 01531 } 01532 01533 ////////////////////////////////////////////////////////////////////////////////////////// 01534 // Get the dual-mode output settings of the XM 01535 XsensResultValue Cmt3::getXmOutputMode(uint8_t& mode) 01536 { 01537 CMT3LOG(__FUNCTION__ "\n"); 01538 CMT3EXITLOG; 01539 01540 DO_DATA_REQUEST_BID(CMT_MID_REQOPMODE,CMT_BID_MASTER); 01541 mode = rcv.getDataByte(); 01542 return m_lastResult = XRV_OK; 01543 } 01544 01545 ////////////////////////////////////////////////////////////////////////////////////////// 01546 // Place all connected sensors into Configuration Mode. 01547 XsensResultValue Cmt3::gotoConfig(void) 01548 { 01549 CMT3LOG(__FUNCTION__ " port %u\n",(uint32_t)m_serial.getCmt1s()->getPortNr()); 01550 CMT3EXITLOG; 01551 01552 Message snd(CMT_MID_GOTOCONFIG); 01553 Message rcv; 01554 int32_t tries = 0; 01555 01556 srand( (unsigned int)timeStampNow()); 01557 01558 m_serial.setTimeout(CMT3_CONFIG_TIMEOUT); 01559 snd.setBusId(CMT_BID_MASTER); 01560 while (tries++ < m_gotoConfigTries) 01561 { 01562 m_serial.getCmt1s()->flushData(); // special case for goto config. we want the buffer to be empty 01563 CMT3LOG(__FUNCTION__ " Attempt to goto config %d\n",tries); 01564 m_serial.writeMessage(&snd); 01565 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_GOTOCONFIGACK,0,false); 01566 #ifndef _PRODUCTION // Production version must retry on nodata, normal versions do not. 01567 if (m_lastResult == XRV_TIMEOUTNODATA) 01568 break; 01569 #endif 01570 if (m_lastResult == XRV_OK) 01571 { 01572 if (m_logging) 01573 m_logFile.writeMessage(&rcv); 01574 if (rcv.getMessageId() == CMT_MID_ERROR) 01575 { 01576 m_lastHwErrorDeviceId = CMT_DID_MASTER; 01577 if (rcv.getDataSize() >= 2) 01578 { 01579 uint8_t biddy = rcv.getDataByte(1); 01580 getDeviceId(biddy,m_lastHwErrorDeviceId); 01581 } 01582 m_lastResult = m_lastHwError = (XsensResultValue) rcv.getDataByte(0); 01583 CMT3LOG(__FUNCTION__ " Goto config failed, error received %d: %s\n",(int32_t)m_lastResult,xsensResultText(m_lastResult)); 01584 m_serial.setTimeout(m_timeoutConf); 01585 return m_lastResult; 01586 } 01587 CMT3LOG(__FUNCTION__ " Goto config succeeded\n"); 01588 m_measuring = false; 01589 m_serial.setTimeout(m_timeoutConf); 01590 return m_lastResult = XRV_OK; 01591 } 01592 m_lastResult = m_serial.getLastResult(); 01593 msleep(((long)rand() * 10)/RAND_MAX); 01594 } 01595 m_serial.setTimeout(m_timeoutConf); 01596 m_serial.getCmt1s()->flushData(); // flush buffers once more to remove any errors that are still there. 01597 m_measuring = (m_lastResult != XRV_OK); 01598 CMT3LOG(__FUNCTION__ " returns %d: %s\n",(int32_t)m_lastResult,xsensResultText(m_lastResult)); 01599 return m_lastResult; 01600 } 01601 01602 ////////////////////////////////////////////////////////////////////////////////////////// 01603 // Place all connected sensors into Measurement Mode. 01604 XsensResultValue Cmt3::gotoMeasurement(void) 01605 { 01606 CMT3LOG(__FUNCTION__ " port %u\n",(uint32_t)m_serial.getCmt1s()->getPortNr()); 01607 CMT3EXITLOG; 01608 01609 Message snd(CMT_MID_GOTOMEASUREMENT); 01610 Message rcv; 01611 01612 snd.setBusId(CMT_BID_MASTER); 01613 01614 m_serial.writeMessage(&snd); 01615 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_GOTOMEASUREMENTACK,0,false); 01616 if (m_lastResult != XRV_OK) 01617 return m_lastResult; 01618 if (m_logging) 01619 m_logFile.writeMessage(&rcv); 01620 HANDLE_ERR_RESULT; 01621 01622 m_rtcInitialized = false; 01623 m_measuring = true; 01624 m_serial.setTimeout(m_timeoutMeas); 01625 return (m_lastResult = XRV_OK); 01626 } 01627 01628 XsensResultValue Cmt3::initBus(void) 01629 { 01630 CMT3LOG(__FUNCTION__ " port %u\n",(uint32_t)m_serial.getCmt1s()->getPortNr()); 01631 CMT3EXITLOG; 01632 01633 DO_DATA_REQUEST_BID(CMT_MID_INITBUS,CMT_BID_MASTER); 01634 return m_lastResult = XRV_OK; // m_serial.waitForMessage(&rcv,CMT_MID_INITBUSRESULTS); 01635 } 01636 01637 ////////////////////////////////////////////////////////////////////////////////////////// 01638 // Return whether the main device is an Xbus Master or not. 01639 bool Cmt3::isXm(void) const 01640 { 01641 return ((m_config.m_masterDeviceId & CMT_DID_TYPEH_MASK) == CMT_DID_TYPEH_XM); 01642 } 01643 01644 ////////////////////////////////////////////////////////////////////////////////////////// 01645 // Open a communication channel to the given serial port name. 01646 XsensResultValue Cmt3::openPort(const char *portName, const uint32_t baudRate, uint32_t readBufSize, uint32_t writeBufSize) 01647 { 01648 CMT3LOG(__FUNCTION__ " port %s @baud %d, timeoutC=%u, timeoutM=%u\n", portName, baudRate, m_timeoutConf, m_timeoutMeas); 01649 CMT3EXITLOG; 01650 01651 if (m_logFile.isOpen()) 01652 return m_lastResult = XRV_ALREADYOPEN; 01653 01654 m_serial.setTimeout(m_timeoutConf); 01655 if ((m_lastResult = m_serial.open(portName, baudRate, readBufSize, writeBufSize)) != XRV_OK) 01656 return m_lastResult; 01657 01658 m_readBufSize = readBufSize; 01659 m_writeBufSize = writeBufSize; 01660 01661 CMT3LOG(__FUNCTION__ " Low level port opened, gotoConfig\n"); 01662 01663 m_baudrate = baudRate; 01664 m_rtcInitialized = false; 01665 m_measuring = true; // required for faster operation of refreshCache 01666 m_logging = false; 01667 01668 // place the device in config mode 01669 if (gotoConfig() != XRV_OK) 01670 { 01671 CMT3LOG(__FUNCTION__ " gotoConfig failed: [%d]%s\n",m_lastResult,xsensResultText(m_lastResult)); 01672 m_serial.close(); 01673 return XRV_CONFIGCHECKFAIL; 01674 } 01675 01676 CMT3LOG(__FUNCTION__ " gotoConfig succeeded, requesting initBus\n"); 01677 Message snd,rcv; 01678 01679 if (initBus() != XRV_OK) 01680 { 01681 CMT3LOG(__FUNCTION__ " initBus failed: [%d]%s\n",m_lastResult,xsensResultText(m_lastResult)); 01682 m_serial.close(); 01683 return XRV_CONFIGCHECKFAIL; 01684 } 01685 01686 CMT3LOG(__FUNCTION__ " initBus succeeded, cleaning up the cache\n"); 01687 if (refreshCache() != XRV_OK) 01688 { 01689 m_serial.close(); 01690 CMT3LOG(__FUNCTION__ " refreshCache failed: [%d]%s\n",m_lastResult,xsensResultText(m_lastResult)); 01691 return XRV_CONFIGCHECKFAIL; 01692 } 01693 01694 CMT3LOG(__FUNCTION__ " returning OK\n"); 01695 return m_lastResult = XRV_OK; 01696 } 01697 01698 #ifdef _WIN32 01699 ////////////////////////////////////////////////////////////////////////////////////////// 01700 // Open a communication channel to the given COM port number. 01701 XsensResultValue Cmt3::openPort(const uint32_t portNumber, const uint32_t baudRate, uint32_t readBufSize, uint32_t writeBufSize) 01702 { 01703 // open the port 01704 CMT3LOG(__FUNCTION__ " port %d @baud %d, timeoutC=%u, timeoutM=%u\n",(int32_t)portNumber,baudRate,m_timeoutConf, m_timeoutMeas); 01705 CMT3EXITLOG; 01706 01707 if (m_logFile.isOpen()) 01708 return m_lastResult = XRV_ALREADYOPEN; 01709 01710 m_serial.setTimeout(m_timeoutConf); // then update L2 (and L1) 01711 if ((m_lastResult = m_serial.open(portNumber, baudRate, readBufSize, writeBufSize)) != XRV_OK) 01712 return m_lastResult; 01713 01714 m_readBufSize = readBufSize; 01715 m_writeBufSize = writeBufSize; 01716 01717 CMT3LOG(__FUNCTION__ " Low level port opened, gotoConfig\n"); 01718 01719 m_baudrate = baudRate; 01720 m_rtcInitialized = false; 01721 m_measuring = true; // required for faster operation of refreshCache 01722 m_logging = false; 01723 01724 // place the device in config mode 01725 if (gotoConfig() != XRV_OK) 01726 { 01727 CMT3LOG(__FUNCTION__ " gotoConfig failed: [%d]%s\n",m_lastResult,xsensResultText(m_lastResult)); 01728 m_serial.close(); 01729 return XRV_CONFIGCHECKFAIL; 01730 } 01731 01732 CMT3LOG(__FUNCTION__ " gotoConfig succeeded, requesting initBus\n"); 01733 Message snd,rcv; 01734 01735 while (initBus() != XRV_OK) 01736 { 01737 if (m_lastResult == XRV_NOBUS) 01738 { 01739 // attempt a bus power up and try again 01740 setBusPowerState(true); 01741 if (initBus() == XRV_OK) 01742 break; 01743 } 01744 01745 CMT3LOG(__FUNCTION__ " initBus failed: [%d]%s\n",m_lastResult,xsensResultText(m_lastResult)); 01746 m_serial.close(); 01747 return XRV_CONFIGCHECKFAIL; 01748 } 01749 01750 CMT3LOG(__FUNCTION__ " initBus succeeded, cleaning up the cache\n"); 01751 if (refreshCache() != XRV_OK) 01752 { 01753 m_serial.close(); 01754 CMT3LOG(__FUNCTION__ " refreshCache failed: [%d]%s\n",m_lastResult,xsensResultText(m_lastResult)); 01755 return XRV_CONFIGCHECKFAIL; 01756 } 01757 01758 CMT3LOG(__FUNCTION__ " returning OK\n"); 01759 return m_lastResult = XRV_OK; 01760 } 01761 #endif 01762 01763 ////////////////////////////////////////////////////////////////////////////////////////// 01764 // Get the MessageId of the next logged message 01765 XsensResultValue Cmt3::peekLogMessageId(uint8_t& messageId) 01766 { 01767 CMT3LOG(__FUNCTION__ "\n"); 01768 CMT3EXITLOG; 01769 01770 if (!m_readFromFile) 01771 return m_lastResult = XRV_INVALIDOPERATION; 01772 01773 Message msg; 01774 01775 CmtFilePos pos = m_logFile.getReadPosition(); 01776 m_lastResult = m_logFile.readMessage(&msg); 01777 m_logFile.setReadPosition(pos); 01778 01779 if (m_lastResult != XRV_OK) 01780 { 01781 CMT3LOG(__FUNCTION__ " no messages to be read\n"); 01782 return m_lastResult; 01783 } 01784 messageId = msg.getMessageId(); 01785 CMT3LOG(__FUNCTION__ " found msg with ID %02x\n",(int32_t) messageId); 01786 return m_lastResult = XRV_OK; 01787 } 01788 01789 ////////////////////////////////////////////////////////////////////////////////////////// 01790 // Retrieve a data message. 01791 XsensResultValue Cmt3::readDataPacket(Packet* pack, bool acceptOther) 01792 { 01793 CMT3LOGDAT(__FUNCTION__ " %p %u\n",pack,acceptOther?1:0); 01794 CMT3EXITLOGDAT; 01795 01796 if (!m_readFromFile) 01797 { 01798 while(1) 01799 { 01800 m_lastResult = m_serial.readMessage(&pack->m_msg); 01801 if (m_lastResult != XRV_OK) 01802 { 01803 CMT3LOGDAT(__FUNCTION__ " no data messages to be read (s)\n"); 01804 return m_lastResult; 01805 } 01806 if (m_logging) 01807 m_logFile.writeMessage(&pack->m_msg); 01808 if (pack->m_msg.getMessageId() == CMT_MID_MTDATA) 01809 { 01810 pack->setXbus(m_config.m_masterDeviceId != m_config.m_deviceInfo[0].m_deviceId,false); 01811 pack->m_itemCount = m_config.m_numberOfDevices; 01812 for (uint16_t i = 0;i < m_config.m_numberOfDevices;++i) 01813 pack->setDataFormat(m_config.m_deviceInfo[i].m_outputMode,m_config.m_deviceInfo[i].m_outputSettings,i); 01814 pack->m_toa = timeStampNow(); 01815 if (m_useRtc) 01816 fillRtc(pack); 01817 CMT3LOGDAT(__FUNCTION__ " data message read (s)\n"); 01818 return m_lastResult = XRV_OK; 01819 } 01820 else if (pack->m_msg.getMessageId() == CMT_MID_ERROR) 01821 { 01822 m_lastHwErrorDeviceId = m_config.m_masterDeviceId; 01823 if (pack->m_msg.getDataSize() >= 2) 01824 { 01825 uint8_t biddy = pack->m_msg.getDataByte(1); 01826 getDeviceId(biddy,m_lastHwErrorDeviceId); 01827 } 01828 return m_lastResult = m_lastHwError = (XsensResultValue) pack->m_msg.getDataByte(0); 01829 } 01830 CMT3LOGDAT(__FUNCTION__ " non-data message read (s): %2x\n",(int32_t) pack->m_msg.getMessageId()); 01831 if (acceptOther) 01832 { 01833 CMT3LOGDAT(__FUNCTION__ " accepting other message (s)\n"); 01834 return m_lastResult = XRV_OTHER; 01835 } 01836 } 01837 } 01838 else 01839 { 01840 while(1) 01841 { 01842 m_lastResult = m_logFile.readMessage(&pack->m_msg); 01843 if (m_lastResult != XRV_OK) 01844 { 01845 CMT3LOGDAT(__FUNCTION__ " no data messages to be read (f)\n"); 01846 return m_lastResult; 01847 } 01848 if (pack->m_msg.getMessageId() == CMT_MID_MTDATA) 01849 { 01850 pack->setXbus(m_config.m_masterDeviceId != m_config.m_deviceInfo[0].m_deviceId,false); 01851 pack->m_itemCount = m_config.m_numberOfDevices; 01852 for (uint16_t i = 0;i < m_config.m_numberOfDevices;++i) 01853 pack->setDataFormat(m_config.m_deviceInfo[i].m_outputMode,m_config.m_deviceInfo[i].m_outputSettings,i); 01854 pack->m_toa = timeStampNow(); 01855 if (m_useRtc) 01856 fillRtc(pack); 01857 CMT3LOGDAT(__FUNCTION__ " data message read (f)\n"); 01858 return m_lastResult = XRV_OK; 01859 } 01860 else if (pack->m_msg.getMessageId() == CMT_MID_ERROR) 01861 { 01862 m_lastHwErrorDeviceId = m_config.m_masterDeviceId; 01863 if (pack->m_msg.getDataSize() >= 2) 01864 { 01865 uint8_t biddy = pack->m_msg.getDataByte(1); 01866 getDeviceId(biddy,m_lastHwErrorDeviceId); 01867 } 01868 return m_lastResult = m_lastHwError = (XsensResultValue) pack->m_msg.getDataByte(0); 01869 } 01870 CMT3LOGDAT(__FUNCTION__ " non-data message read (f): %2x\n",(int32_t) pack->m_msg.getMessageId()); 01871 if (acceptOther) 01872 { 01873 CMT3LOGDAT(__FUNCTION__ " accepting other message (f)\n"); 01874 return m_lastResult = XRV_OTHER; 01875 } 01876 } 01877 } 01878 } 01879 01880 ////////////////////////////////////////////////////////////////////////////////////////// 01881 // Request a data message and wait for it to arrive. 01882 XsensResultValue Cmt3::requestData(Packet* pack, const uint8_t *data, const uint16_t count) 01883 { 01884 CMT3LOGDAT(__FUNCTION__ " %p\n",pack); 01885 CMT3EXITLOGDAT; 01886 01887 if (isXm()) 01888 return m_lastResult = XRV_INVALIDOPERATION; 01889 Message snd(CMT_MID_REQDATA); 01890 snd.setDataBuffer(data, 0, count); 01891 m_lastResult = m_serial.writeMessage(&snd); 01892 if (m_lastResult != XRV_OK) 01893 return m_lastResult; 01894 m_lastResult = m_serial.waitForMessage(&pack->m_msg,CMT_MID_MTDATA,0,true); 01895 if (m_lastResult != XRV_OK) 01896 return m_lastResult; 01897 for (uint16_t i = 0;i < m_config.m_numberOfDevices;++i) 01898 pack->setDataFormat(m_config.m_deviceInfo[i].m_outputMode, m_config.m_deviceInfo[i].m_outputSettings,i); 01899 if (m_logging) 01900 m_logFile.writeMessage(&pack->m_msg); 01901 if (pack->m_msg.getMessageId() == CMT_MID_ERROR) 01902 { 01903 m_lastHwErrorDeviceId = m_config.m_masterDeviceId; 01904 if (pack->m_msg.getDataSize() >= 2) 01905 { 01906 uint8_t biddy = pack->m_msg.getDataByte(1); 01907 getDeviceId(biddy,m_lastHwErrorDeviceId); 01908 } 01909 return m_lastResult = m_lastHwError = (XsensResultValue) pack->m_msg.getDataByte(); 01910 } 01911 return m_lastResult; 01912 } 01913 01914 ////////////////////////////////////////////////////////////////////////////////////////// 01915 // Reset all connected sensors. 01916 XsensResultValue Cmt3::reset(void) 01917 { 01918 CMT3LOG(__FUNCTION__ "\n"); 01919 CMT3EXITLOG; 01920 01921 Message snd(CMT_MID_RESET,0); 01922 Message rcv; 01923 snd.setBusId(CMT_BID_MASTER); 01924 m_serial.writeMessage(&snd); 01925 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_RESETACK,100,false); 01926 if (m_lastResult != XRV_OK) 01927 return m_lastResult; 01928 if (m_logging) 01929 m_logFile.writeMessage(&rcv); 01930 bool wasMeasuring = m_measuring; 01931 m_measuring = true; 01932 refreshCache(); 01933 if (wasMeasuring) 01934 gotoMeasurement(); 01935 return m_lastResult = XRV_OK; 01936 } 01937 01938 ////////////////////////////////////////////////////////////////////////////////////////// 01939 //! Perform an orientation reset on a device. 01940 XsensResultValue Cmt3::resetOrientation(const CmtResetMethod method, const CmtDeviceId deviceId) 01941 { 01942 CMT3LOG(__FUNCTION__ " %u %08x\n",(uint32_t) method,deviceId); 01943 CMT3EXITLOG; 01944 01945 DO_DATA_SET(CMT_MID_RESETORIENTATION,CMT_LEN_RESETORIENTATION,Short,(uint16_t) method); 01946 return m_lastResult = XRV_OK; 01947 } 01948 01949 ////////////////////////////////////////////////////////////////////////////////////////// 01950 //! Initiates the XKF3 'no rotation' update procedure. 01951 XsensResultValue Cmt3::setNoRotation(const uint16_t duration, const CmtDeviceId deviceId) 01952 { 01953 CMT3LOG(__FUNCTION__ " %u %08x\n",(uint32_t) duration,deviceId); 01954 CMT3EXITLOG; 01955 01956 DO_DATA_SET(CMT_MID_SETNOROTATION,CMT_LEN_SETNOROTATION,Short,(uint16_t) duration); 01957 return m_lastResult = XRV_OK; 01958 } 01959 01960 ////////////////////////////////////////////////////////////////////////////////////////// 01961 //! Restore the factory defaults of a device. 01962 XsensResultValue Cmt3::restoreFactoryDefaults(const CmtDeviceId deviceId) 01963 { 01964 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 01965 CMT3EXITLOG; 01966 01967 DO_DATA_REQUEST(CMT_MID_RESTOREFACTORYDEF); 01968 return m_lastResult = XRV_OK; 01969 } 01970 01971 #if 0 01972 obsolete: 01973 ////////////////////////////////////////////////////////////////////////////////////////// 01974 // Set the state (enabled/disabled) of the AMD algorithm 01975 XsensResultValue Cmt3::setAmdState (const bool state, const CmtDeviceId deviceId) 01976 { 01977 CMT3LOG(__FUNCTION__ " %u %08x\n",state?1:0,deviceId); 01978 CMT3EXITLOG; 01979 01980 uint16_t dat = ((state)?1:0); 01981 DO_DATA_SET(CMT_MID_REQAMD,CMT_LEN_AMD,Short,dat); 01982 return m_lastResult = XRV_OK; 01983 } 01984 #endif 01985 01986 ////////////////////////////////////////////////////////////////////////////////////////// 01987 // Set the baudrate and reconnect at the new baudrate if successful. 01988 XsensResultValue Cmt3::setBaudrate(const uint32_t baudrate, bool reconnect) 01989 { 01990 CMT3LOG(__FUNCTION__ " %u %u\n",baudrate,reconnect?1:0); 01991 CMT3EXITLOG; 01992 01993 uint8_t tmp; 01994 switch (baudrate) 01995 { 01996 case CMT_BAUD_RATE_4800: 01997 tmp = CMT_BAUDCODE_4K8; 01998 break; 01999 case CMT_BAUD_RATE_9600: 02000 tmp = CMT_BAUDCODE_9K6; 02001 break; 02002 // case CMT_BAUD_RATE_14K4: 02003 // tmp = CMT_BAUDCODE_14K4; 02004 // break; 02005 case CMT_BAUD_RATE_19K2: 02006 tmp = CMT_BAUDCODE_19K2; 02007 break; 02008 // case CMT_BAUD_RATE_28K8: 02009 // tmp = CMT_BAUDCODE_28K8; 02010 // break; 02011 case CMT_BAUD_RATE_38K4: 02012 tmp = CMT_BAUDCODE_38K4; 02013 break; 02014 case CMT_BAUD_RATE_57K6: 02015 tmp = CMT_BAUDCODE_57K6; 02016 break; 02017 // case CMT_BAUD_RATE_76K8: 02018 // tmp = CMT_BAUDCODE_76K8; 02019 // break; 02020 case CMT_BAUD_RATE_115K2: 02021 tmp = CMT_BAUDCODE_115K2; 02022 break; 02023 case CMT_BAUD_RATE_230K4: 02024 tmp = CMT_BAUDCODE_230K4; 02025 break; 02026 case CMT_BAUD_RATE_460K8: 02027 tmp = CMT_BAUDCODE_460K8; 02028 break; 02029 case CMT_BAUD_RATE_921K6: 02030 tmp = CMT_BAUDCODE_921K6; 02031 break; 02032 default: 02033 return m_lastResult = XRV_BAUDRATEINVALID; 02034 } 02035 02036 if (baudrate != m_baudrate) { 02037 DO_DATA_SET_BID(CMT_MID_REQBAUDRATE,CMT_LEN_BAUDRATE,Byte,tmp,CMT_BID_MASTER); 02038 02039 if (reconnect) 02040 { 02041 CMT3LOG(__FUNCTION__ " sending reset for reconnect\n"); 02042 // Reset devices on this port and reopen port @ new baudrate 02043 Message sndReset(CMT_MID_RESET,0); 02044 Message rcvReset; 02045 sndReset.setBusId(CMT_BID_MASTER); 02046 m_serial.writeMessage(&sndReset); 02047 m_lastResult = m_serial.waitForMessage(&rcvReset,CMT_MID_RESETACK,0,false); 02048 if (m_lastResult != XRV_OK) 02049 return m_lastResult; 02050 if (m_logging) 02051 m_logFile.writeMessage(&rcvReset); 02052 bool wasMeasuring = m_measuring; 02053 m_measuring = true; 02054 02055 // XM needs time to reboot 02056 if (isXm()) 02057 msleep(750); 02058 02059 CMT3LOG(__FUNCTION__ " reopening port at new baud rate\n"); 02060 #ifdef _WIN32 02061 int32_t port; 02062 m_serial.getPortNr(port); 02063 closePort(false); 02064 m_lastResult = openPort(port, baudrate, m_readBufSize, m_writeBufSize); 02065 #else 02066 char portname[32]; 02067 m_serial.getPortName(portname); 02068 closePort(false); 02069 m_lastResult = openPort(portname, baudrate, m_readBufSize, m_writeBufSize); 02070 #endif 02071 if (m_lastResult != XRV_OK) 02072 return m_lastResult; 02073 if (wasMeasuring) 02074 gotoMeasurement(); 02075 return m_lastResult; 02076 } 02077 } 02078 02079 return m_lastResult = XRV_OK; 02080 } 02081 02082 ////////////////////////////////////////////////////////////////////////////////////////// 02083 // Set the state of the bluetooth communication to on (true) or off (false) 02084 XsensResultValue Cmt3::setBluetoothState(const bool enabled) 02085 { 02086 CMT3LOG(__FUNCTION__ " %u\n",enabled?1:0); 02087 CMT3EXITLOG; 02088 02089 uint8_t dat = (enabled?0:1); 02090 DO_DATA_SET_BID(CMT_MID_REQBTDISABLE,CMT_LEN_BTDISABLE,Byte,dat,CMT_BID_MASTER); 02091 return m_lastResult = XRV_OK; 02092 } 02093 02094 ////////////////////////////////////////////////////////////////////////////////////////// 02095 // Switch the XM bus power on or off. 02096 XsensResultValue Cmt3::setBusPowerState(const bool enabled) 02097 { 02098 CMT3LOG(__FUNCTION__ " %u\n",enabled?1:0); 02099 CMT3EXITLOG; 02100 02101 uint16_t tmp = enabled?1:0; 02102 DO_DATA_SET_BID(CMT_MID_BUSPWR,CMT_LEN_BUSPWR,Short,tmp,CMT_BID_MASTER); 02103 return m_lastResult = XRV_OK; 02104 } 02105 02106 ////////////////////////////////////////////////////////////////////////////////////////// 02107 // Set the complete device output mode of a device. 02108 XsensResultValue Cmt3::setDeviceMode (const CmtDeviceMode& mode, bool force, const CmtDeviceId deviceId) 02109 { 02110 CMT3LOG(__FUNCTION__ " %04x %08x %u %u %08x\n",(uint32_t) mode.m_outputMode,(uint32_t) mode.m_outputSettings,(uint32_t) mode.m_sampleFrequency,force?1:0,deviceId); 02111 CMT3EXITLOG; 02112 02113 CmtDeviceMode2 mode2; 02114 mode2.m_outputMode = mode.m_outputMode; 02115 mode2.m_outputSettings = mode.m_outputSettings; 02116 mode2.setSampleFrequency(mode.m_sampleFrequency); 02117 02118 return setDeviceMode2(mode2, force, deviceId); 02119 } 02120 02121 ////////////////////////////////////////////////////////////////////////////////////////// 02122 // Set the complete device output mode of a device. 02123 XsensResultValue Cmt3::setDeviceMode2 (const CmtDeviceMode2& mode, bool force, const CmtDeviceId deviceId) 02124 { 02125 CMT3LOG(__FUNCTION__ " %04x %08x %u %u %u %08x\n",(uint32_t) mode.m_outputMode,(uint32_t) mode.m_outputSettings,(uint32_t) mode.m_period, (uint32_t)mode.m_skip,force?1:0,deviceId); 02126 CMT3EXITLOG; 02127 02128 Message snd; 02129 Message rcv; 02130 uint8_t bid = getBusIdInternal(deviceId); 02131 if (bid == CMT_BID_INVALID) 02132 return (m_lastResult = XRV_INVALIDID); 02133 02134 //uint16_t period, skip; 02135 //mode.getPeriodAndSkipFactor(period, skip); 02136 uint16_t xperiod; 02137 //bool changed = false; 02138 02139 bool xm = isXm(); 02140 if (bid == CMT_BID_BROADCAST) 02141 { 02142 if (xm) 02143 { 02144 // set the device modes of all connected devices first 02145 for (uint16_t i = 0; i < m_config.m_numberOfDevices;++i) 02146 if ((m_lastResult = setDeviceMode2(mode,force,m_config.m_deviceInfo[i].m_deviceId)) != XRV_OK) 02147 return m_lastResult; 02148 } 02149 bid = CMT_BID_MASTER; 02150 } 02151 02152 // set sample frequency if this is an Xbus Master or the primary device 02153 if (deviceId == CMT_DID_BROADCAST || deviceId == m_config.m_masterDeviceId) 02154 { 02155 m_period = mode.m_period; 02156 m_skip = mode.m_skip; 02157 //m_sampleFrequency = (double) mode.getSampleFrequency(); 02158 snd.setBusId(CMT_BID_MASTER); 02159 if (xm) 02160 xperiod = mode.m_period * (mode.m_skip + 1); 02161 else 02162 xperiod = mode.m_period; 02163 02164 if (force || m_config.m_samplingPeriod != xperiod) 02165 { 02166 CMT3LOG(__FUNCTION__ " setting device %08x period to %u\n",deviceId,(uint32_t) xperiod); 02167 //changed = true; 02168 snd.setDataShort(xperiod); 02169 snd.setMessageId(CMT_MID_REQPERIOD); 02170 m_serial.writeMessage(&snd); 02171 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQPERIODACK,0,true); 02172 if (m_lastResult != XRV_OK) 02173 return m_lastResult; 02174 if (m_logging) 02175 m_logFile.writeMessage(&rcv); 02176 HANDLE_ERR_RESULT; 02177 m_config.m_samplingPeriod = xperiod; // update device info 02178 } 02179 02180 if (!xm && (force || m_config.m_outputSkipFactor != mode.m_skip)) 02181 { 02182 CMT3LOG(__FUNCTION__ " setting MT %08x skip factor to %u\n",deviceId,(uint32_t) mode.m_skip); 02183 //changed = true; 02184 snd.setDataShort(mode.m_skip); 02185 snd.setMessageId(CMT_MID_REQOUTPUTSKIPFACTOR); 02186 m_serial.writeMessage(&snd); 02187 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQOUTPUTSKIPFACTORACK,0,true); 02188 if (m_lastResult != XRV_OK) 02189 return m_lastResult; 02190 if (m_logging) 02191 m_logFile.writeMessage(&rcv); 02192 HANDLE_ERR_RESULT; 02193 m_config.m_outputSkipFactor = mode.m_skip; // update device info 02194 } 02195 } 02196 02197 // set the output mode and settings if this device is not an Xbus Master 02198 if ((deviceId & CMT_DID_TYPEH_MASK) != CMT_DID_TYPEH_XM) 02199 { 02200 if (bid == CMT_BID_BROADCAST || bid == CMT_BID_MASTER) { 02201 snd.setBusId(CMT_BID_MASTER); 02202 bid = 1; 02203 } 02204 else 02205 snd.setBusId(bid); 02206 02207 if (force || m_config.m_deviceInfo[bid-1].m_outputMode != (uint16_t) mode.m_outputMode) 02208 { 02209 CMT3LOG(__FUNCTION__ " setting MT %08x output mode to %04X\n",deviceId,(uint32_t) mode.m_outputMode); 02210 //changed = true; 02211 snd.resizeData(2); 02212 snd.setMessageId(CMT_MID_REQOUTPUTMODE); 02213 snd.setDataShort((uint16_t) mode.m_outputMode); 02214 m_serial.writeMessage(&snd); 02215 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQOUTPUTMODEACK,0,true); 02216 if (m_lastResult != XRV_OK) 02217 return m_lastResult; 02218 if (m_logging) 02219 m_logFile.writeMessage(&rcv); 02220 HANDLE_ERR_RESULT; 02221 m_config.m_deviceInfo[bid-1].m_outputMode = (uint16_t) mode.m_outputMode; // update device info 02222 } 02223 02224 uint32_t settings = (uint32_t) mode.m_outputSettings; 02225 if (xm) 02226 settings &= ~(uint32_t) CMT_OUTPUTSETTINGS_TIMESTAMP_MASK; 02227 02228 if (force || m_config.m_deviceInfo[bid-1].m_outputSettings != settings) 02229 { 02230 CMT3LOG(__FUNCTION__ " setting MT %08x output settings to %08X\n",deviceId,(uint32_t) settings); 02231 //changed = true; 02232 snd.setMessageId(CMT_MID_REQOUTPUTSETTINGS); 02233 snd.setDataLong(settings); 02234 m_serial.writeMessage(&snd); 02235 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQOUTPUTSETTINGSACK,0,true); 02236 if (m_lastResult != XRV_OK) 02237 return m_lastResult; 02238 if (m_logging) 02239 m_logFile.writeMessage(&rcv); 02240 HANDLE_ERR_RESULT; 02241 m_config.m_deviceInfo[bid-1].m_outputSettings = settings; // update device info 02242 } 02243 } 02244 02245 return m_lastResult = XRV_OK; 02246 } 02247 02248 ////////////////////////////////////////////////////////////////////////////////////////// 02249 // Retrieve the error mode 02250 XsensResultValue Cmt3::setErrorMode(const uint16_t mode) 02251 { 02252 CMT3LOG(__FUNCTION__ " %u\n",(uint32_t) mode); 02253 CMT3EXITLOG; 02254 02255 uint8_t mid; 02256 if (isXm()) 02257 mid = CMT_MID_REQXMERRORMODE; 02258 else 02259 mid = CMT_MID_REQERRORMODE; 02260 02261 DO_DATA_SET_BID(mid,CMT_LEN_ERRORMODE,Short,mode,CMT_BID_MASTER); 02262 return m_lastResult = XRV_OK; 02263 } 02264 02265 ////////////////////////////////////////////////////////////////////////////////////////// 02266 // Set the number of times the gotoConfig function will attempt gotoConfig before failing 02267 XsensResultValue Cmt3::setGotoConfigTries(const uint16_t tries) 02268 { 02269 CMT3LOG(__FUNCTION__ " %u\n",(uint32_t) tries); 02270 CMT3EXITLOG; 02271 02272 m_gotoConfigTries = tries; 02273 return m_lastResult = XRV_OK; 02274 } 02275 02276 ////////////////////////////////////////////////////////////////////////////////////////// 02277 // Set the heading offset of a device. The valid range is -pi to +pi. 02278 XsensResultValue Cmt3::setHeading (const double heading, const CmtDeviceId deviceId) 02279 { 02280 CMT3LOG(__FUNCTION__ " %f %08x\n",heading,deviceId); 02281 CMT3EXITLOG; 02282 02283 DO_DATA_SET(CMT_MID_REQHEADING,CMT_LEN_HEADING,Float,(float) heading); 02284 return m_lastResult = XRV_OK; 02285 } 02286 02287 ////////////////////////////////////////////////////////////////////////////////////////// 02288 // Sets the current position of the sensor 02289 XsensResultValue Cmt3::setLatLonAlt(const CmtVector& lla, const CmtDeviceId deviceId) 02290 { 02291 CMT3LOG(__FUNCTION__ " [%f %f %f] %08x\n",lla.m_data[0],lla.m_data[1],lla.m_data[2],deviceId); 02292 CMT3EXITLOG; 02293 02294 uint8_t bid = getBusIdInternal(deviceId); 02295 if (bid == CMT_BID_INVALID || bid == CMT_BID_BROADCAST) 02296 return (m_lastResult = XRV_INVALIDID); 02297 02298 Message snd(CMT_MID_SETLATLONALT,CMT_LEN_LATLONALT); 02299 Message rcv; 02300 snd.setDataFloat((float) lla.m_data[0],0); 02301 snd.setDataFloat((float) lla.m_data[1],4); 02302 snd.setDataFloat((float) lla.m_data[2],8); 02303 02304 snd.setBusId(bid); 02305 m_serial.writeMessage(&snd); 02306 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_SETLATLONALTACK,0,true); 02307 if (m_lastResult != XRV_OK) 02308 return m_lastResult; 02309 if (m_logging) 02310 m_logFile.writeMessage(&rcv); 02311 if (rcv.getMessageId() == CMT_MID_ERROR) 02312 { 02313 m_lastHwErrorDeviceId = m_config.m_masterDeviceId; 02314 if (rcv.getDataSize() >= 2) 02315 { 02316 uint8_t biddy = rcv.getDataByte(1); 02317 getDeviceId(biddy,m_lastHwErrorDeviceId); 02318 } 02319 return m_lastResult = m_lastHwError = (XsensResultValue) rcv.getDataByte(); 02320 } 02321 return m_lastResult = XRV_OK; 02322 } 02323 02324 ////////////////////////////////////////////////////////////////////////////////////////// 02325 // Set the location ID of a device. The buffer should be no more than 20 bytes. 02326 XsensResultValue Cmt3::setLocationId (uint16_t locationId, const CmtDeviceId deviceId) 02327 { 02328 CMT3LOG(__FUNCTION__ " %u %08x\n",(uint32_t) locationId,deviceId); 02329 CMT3EXITLOG; 02330 02331 DO_DATA_SET(CMT_MID_REQLOCATIONID,CMT_LEN_LOCATIONID,Short,locationId); 02332 return m_lastResult = XRV_OK; 02333 } 02334 02335 ////////////////////////////////////////////////////////////////////////////////////////// 02336 // Set the magnetic declination offset of a device. The valid range is -pi to +pi. 02337 XsensResultValue Cmt3::setMagneticDeclination(const double declination, const CmtDeviceId deviceId) 02338 { 02339 CMT3LOG(__FUNCTION__ " %f %08x\n",declination,deviceId); 02340 CMT3EXITLOG; 02341 02342 DO_DATA_SET(CMT_MID_SETMAGNETICDECLINATION,CMT_LEN_MAGNETICDECLINATION,Float,(float) declination); 02343 return m_lastResult = XRV_OK; 02344 } 02345 02346 XsensResultValue Cmt3::setObjectAlignmentMatrix(const CmtMatrix& matrix, const CmtDeviceId deviceId) 02347 { 02348 CMT3LOG(__FUNCTION__ " [[%f %f %f][%f %f %f][%f %f %f]] %08x\n", 02349 matrix.m_data[0][0],matrix.m_data[0][1],matrix.m_data[0][2], 02350 matrix.m_data[1][0],matrix.m_data[1][1],matrix.m_data[1][2], 02351 matrix.m_data[2][0],matrix.m_data[2][1],matrix.m_data[2][2],deviceId); 02352 CMT3EXITLOG; 02353 02354 uint8_t bid = getBusIdInternal(deviceId); 02355 if (bid == CMT_BID_INVALID || bid == CMT_BID_BROADCAST) 02356 return (m_lastResult = XRV_INVALIDID); 02357 02358 Message snd(CMT_MID_SETOBJECTALIGNMENT,CMT_LEN_OBJECTALIGNMENT); 02359 Message rcv; 02360 snd.setDataFloat((float) matrix.m_data[0][0],0); 02361 snd.setDataFloat((float) matrix.m_data[0][1],4); 02362 snd.setDataFloat((float) matrix.m_data[0][2],8); 02363 snd.setDataFloat((float) matrix.m_data[1][0],12); 02364 snd.setDataFloat((float) matrix.m_data[1][1],16); 02365 snd.setDataFloat((float) matrix.m_data[1][2],20); 02366 snd.setDataFloat((float) matrix.m_data[2][0],24); 02367 snd.setDataFloat((float) matrix.m_data[2][1],28); 02368 snd.setDataFloat((float) matrix.m_data[2][2],32); 02369 02370 snd.setBusId(bid); 02371 m_serial.writeMessage(&snd); 02372 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_SETOBJECTALIGNMENTACK,0,true); 02373 if (m_lastResult != XRV_OK) 02374 return m_lastResult; 02375 if (m_logging) 02376 m_logFile.writeMessage(&rcv); 02377 if (rcv.getMessageId() == CMT_MID_ERROR) 02378 { 02379 m_lastHwErrorDeviceId = m_config.m_masterDeviceId; 02380 if (rcv.getDataSize() >= 2) 02381 { 02382 uint8_t biddy = rcv.getDataByte(1); 02383 getDeviceId(biddy,m_lastHwErrorDeviceId); 02384 } 02385 return m_lastResult = m_lastHwError = (XsensResultValue) rcv.getDataByte(); 02386 } 02387 return m_lastResult = XRV_OK; 02388 } 02389 02390 ////////////////////////////////////////////////////////////////////////////////////////// 02391 // Set the processing flags of a device. 02392 XsensResultValue Cmt3::setProcessingFlags (uint16_t processingFlags, const CmtDeviceId deviceId) 02393 { 02394 CMT3LOG(__FUNCTION__ " %u %08x\n",(uint32_t) processingFlags,deviceId); 02395 CMT3EXITLOG; 02396 02397 DO_DATA_SET(CMT_MID_REQPROCESSINGFLAGS,CMT_LEN_PROCESSINGFLAGS,Short,processingFlags); 02398 return m_lastResult = XRV_OK; 02399 } 02400 02401 ////////////////////////////////////////////////////////////////////////////////////////// 02402 // Switch the XM off 02403 XsensResultValue Cmt3::setXmPowerOff(void) 02404 { 02405 CMT3LOG(__FUNCTION__ "\n"); 02406 CMT3EXITLOG; 02407 02408 if (!isXm()) 02409 return m_lastResult = XRV_INVALIDOPERATION; 02410 Message snd(CMT_MID_XMPWROFF,0); 02411 snd.setBusId(CMT_BID_MASTER); 02412 return m_lastResult = m_serial.writeMessage(&snd); 02413 } 02414 02415 ////////////////////////////////////////////////////////////////////////////////////////// 02416 // Set the inbound synchronization settings of a device. 02417 XsensResultValue Cmt3::setSyncInSettings (const CmtSyncInSettings& settings) 02418 { 02419 CMT3LOG(__FUNCTION__ " %u %u %u\n",(uint32_t) settings.m_mode,settings.m_offset,(uint32_t) settings.m_skipFactor); 02420 CMT3EXITLOG; 02421 02422 if (isXm()) 02423 return m_lastResult = XRV_INVALIDOPERATION; 02424 02425 Message snd(CMT_MID_REQSYNCINSETTINGS,3); 02426 Message rcv; 02427 02428 snd.setBusId(CMT_BID_MASTER); 02429 02430 snd.setDataByte(CMT_PARAM_SYNCIN_MODE); 02431 snd.setDataShort(settings.m_mode,1); 02432 m_serial.writeMessage(&snd); 02433 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCINSETTINGSACK,0,true); 02434 if (m_lastResult != XRV_OK) 02435 return m_lastResult; 02436 if (m_logging) 02437 m_logFile.writeMessage(&rcv); 02438 HANDLE_ERR_RESULT; 02439 02440 snd.setDataByte(CMT_PARAM_SYNCIN_SKIPFACTOR); 02441 snd.setDataShort(settings.m_skipFactor,1); 02442 m_serial.writeMessage(&snd); 02443 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCINSETTINGSACK,0,true); 02444 if (m_lastResult != XRV_OK) 02445 return m_lastResult; 02446 if (m_logging) 02447 m_logFile.writeMessage(&rcv); 02448 HANDLE_ERR_RESULT; 02449 02450 snd.setDataByte(CMT_PARAM_SYNCIN_OFFSET); 02451 snd.setDataLong((uint32_t) (((double) settings.m_offset) 02452 * CMT_SYNC_CLOCK_NS_TO_TICKS + 0.5),1); 02453 m_serial.writeMessage(&snd); 02454 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCINSETTINGSACK,0,true); 02455 if (m_lastResult == XRV_OK) 02456 { 02457 if (m_logging) 02458 m_logFile.writeMessage(&rcv); 02459 HANDLE_ERR_RESULT; 02460 } 02461 02462 return m_lastResult; 02463 } 02464 02465 ////////////////////////////////////////////////////////////////////////////////////////// 02466 // Set the inbound synchronization mode of a device. 02467 XsensResultValue Cmt3::setSyncInMode (const uint16_t mode) 02468 { 02469 CMT3LOG(__FUNCTION__ " %u\n",(uint32_t) mode); 02470 CMT3EXITLOG; 02471 02472 if (isXm()) 02473 return m_lastResult = XRV_INVALIDOPERATION; 02474 02475 Message snd(CMT_MID_REQSYNCINSETTINGS,3); 02476 Message rcv; 02477 02478 snd.setBusId(CMT_BID_MASTER); 02479 02480 snd.setDataByte(CMT_PARAM_SYNCIN_MODE); 02481 snd.setDataShort(mode,1); 02482 m_serial.writeMessage(&snd); 02483 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCINSETTINGSACK,0,true); 02484 if (m_lastResult != XRV_OK) 02485 return m_lastResult; 02486 if (m_logging) 02487 m_logFile.writeMessage(&rcv); 02488 HANDLE_ERR_RESULT; 02489 02490 return m_lastResult; 02491 } 02492 02493 ////////////////////////////////////////////////////////////////////////////////////////// 02494 // Set the inbound synchronization skip factor of a device. 02495 XsensResultValue Cmt3::setSyncInSkipFactor (const uint16_t skipFactor) 02496 { 02497 CMT3LOG(__FUNCTION__ " %u\n",skipFactor); 02498 CMT3EXITLOG; 02499 02500 if (isXm()) 02501 return m_lastResult = XRV_INVALIDOPERATION; 02502 02503 Message snd(CMT_MID_REQSYNCINSETTINGS,3); 02504 Message rcv; 02505 02506 snd.setBusId(CMT_BID_MASTER); 02507 02508 snd.setDataByte(CMT_PARAM_SYNCIN_SKIPFACTOR); 02509 snd.setDataShort(skipFactor,1); 02510 m_serial.writeMessage(&snd); 02511 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCINSETTINGSACK,0,true); 02512 if (m_lastResult != XRV_OK) 02513 return m_lastResult; 02514 if (m_logging) 02515 m_logFile.writeMessage(&rcv); 02516 HANDLE_ERR_RESULT; 02517 02518 return m_lastResult; 02519 } 02520 02521 ////////////////////////////////////////////////////////////////////////////////////////// 02522 // Set the inbound synchronization offset of a device. 02523 XsensResultValue Cmt3::setSyncInOffset (const uint32_t offset) 02524 { 02525 CMT3LOG(__FUNCTION__ " %u\n",offset); 02526 CMT3EXITLOG; 02527 02528 if (isXm()) 02529 return m_lastResult = XRV_INVALIDOPERATION; 02530 02531 Message snd(CMT_MID_REQSYNCINSETTINGS,3); 02532 Message rcv; 02533 02534 snd.setBusId(CMT_BID_MASTER); 02535 02536 snd.setDataByte(CMT_PARAM_SYNCIN_OFFSET); 02537 snd.setDataLong((uint32_t) (((double) offset) 02538 * CMT_SYNC_CLOCK_NS_TO_TICKS + 0.5),1); 02539 m_serial.writeMessage(&snd); 02540 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCINSETTINGSACK,0,true); 02541 if (m_lastResult == XRV_OK) 02542 { 02543 if (m_logging) 02544 m_logFile.writeMessage(&rcv); 02545 HANDLE_ERR_RESULT; 02546 } 02547 02548 return m_lastResult; 02549 } 02550 02551 02552 ////////////////////////////////////////////////////////////////////////////////////////// 02553 // Set the synchronization mode of the XM 02554 XsensResultValue Cmt3::setSyncMode(const uint8_t mode) 02555 { 02556 CMT3LOG(__FUNCTION__ " %u\n",(uint32_t) mode); 02557 CMT3EXITLOG; 02558 02559 if (!isXm()) 02560 return m_lastResult = XRV_INVALIDOPERATION; 02561 02562 DO_DATA_SET_BID(CMT_MID_REQSYNCMODE,CMT_LEN_SYNCMODE,Byte,mode,CMT_BID_MASTER); 02563 return m_lastResult = XRV_OK; 02564 } 02565 02566 ////////////////////////////////////////////////////////////////////////////////////////// 02567 // Set the outbound synchronization settings of a device. 02568 XsensResultValue Cmt3::setSyncOutSettings (const CmtSyncOutSettings& settings) 02569 { 02570 CMT3LOG(__FUNCTION__ " %u %u %u %u\n",(uint32_t) settings.m_mode, settings.m_offset, (uint32_t) settings.m_pulseWidth, (uint32_t) settings.m_skipFactor); 02571 CMT3EXITLOG; 02572 02573 if (isXm()) 02574 return m_lastResult = XRV_INVALIDOPERATION; 02575 02576 Message snd(CMT_MID_REQSYNCOUTSETTINGS,3); 02577 Message rcv; 02578 02579 snd.setBusId(CMT_BID_MASTER); 02580 02581 snd.setDataByte(CMT_PARAM_SYNCOUT_MODE); 02582 snd.setDataShort(settings.m_mode,1); 02583 m_serial.writeMessage(&snd); 02584 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 02585 if (m_lastResult != XRV_OK) 02586 return m_lastResult; 02587 if (m_logging) 02588 m_logFile.writeMessage(&rcv); 02589 HANDLE_ERR_RESULT; 02590 02591 snd.setDataByte(CMT_PARAM_SYNCOUT_SKIPFACTOR); 02592 snd.setDataShort(settings.m_skipFactor,1); 02593 m_serial.writeMessage(&snd); 02594 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 02595 if (m_lastResult != XRV_OK) 02596 return m_lastResult; 02597 if (m_logging) 02598 m_logFile.writeMessage(&rcv); 02599 HANDLE_ERR_RESULT; 02600 02601 snd.setDataByte(CMT_PARAM_SYNCOUT_OFFSET); 02602 snd.setDataLong((uint32_t) (((double) settings.m_offset) 02603 * CMT_SYNC_CLOCK_NS_TO_TICKS + 0.5),1); 02604 m_serial.writeMessage(&snd); 02605 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 02606 if (m_lastResult != XRV_OK) 02607 return m_lastResult; 02608 if (m_logging) 02609 m_logFile.writeMessage(&rcv); 02610 HANDLE_ERR_RESULT; 02611 02612 snd.setDataByte(CMT_PARAM_SYNCOUT_PULSEWIDTH); 02613 snd.setDataLong((uint32_t) (((double) settings.m_pulseWidth) 02614 * CMT_SYNC_CLOCK_NS_TO_TICKS + 0.5),1); 02615 m_serial.writeMessage(&snd); 02616 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 02617 if (m_lastResult != XRV_OK) 02618 return m_lastResult; 02619 if (m_logging) 02620 m_logFile.writeMessage(&rcv); 02621 HANDLE_ERR_RESULT; 02622 02623 return m_lastResult = XRV_OK; 02624 } 02625 02626 ////////////////////////////////////////////////////////////////////////////////////////// 02627 // Set the outbound synchronization mode of a device. 02628 XsensResultValue Cmt3::setSyncOutMode (const uint16_t mode) 02629 { 02630 CMT3LOG(__FUNCTION__ " %u\n",(uint32_t) mode); 02631 CMT3EXITLOG; 02632 02633 if (isXm()) 02634 return m_lastResult = XRV_INVALIDOPERATION; 02635 02636 Message snd(CMT_MID_REQSYNCOUTSETTINGS,3); 02637 Message rcv; 02638 02639 snd.setBusId(CMT_BID_MASTER); 02640 02641 snd.setDataByte(CMT_PARAM_SYNCOUT_MODE); 02642 snd.setDataShort(mode,1); 02643 m_serial.writeMessage(&snd); 02644 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 02645 if (m_lastResult != XRV_OK) 02646 return m_lastResult; 02647 if (m_logging) 02648 m_logFile.writeMessage(&rcv); 02649 HANDLE_ERR_RESULT; 02650 02651 return m_lastResult = XRV_OK; 02652 } 02653 02654 ////////////////////////////////////////////////////////////////////////////////////////// 02655 // Set the outbound synchronization pulse width of a device. 02656 XsensResultValue Cmt3::setSyncOutPulseWidth(const uint32_t pulseWidth) 02657 { 02658 CMT3LOG(__FUNCTION__ " %u\n",pulseWidth); 02659 CMT3EXITLOG; 02660 02661 if (isXm()) 02662 return m_lastResult = XRV_INVALIDOPERATION; 02663 02664 Message snd(CMT_MID_REQSYNCOUTSETTINGS,3); 02665 Message rcv; 02666 02667 snd.setBusId(CMT_BID_MASTER); 02668 02669 snd.setDataByte(CMT_PARAM_SYNCOUT_PULSEWIDTH); 02670 snd.setDataLong((uint32_t) (((double) pulseWidth) 02671 * CMT_SYNC_CLOCK_NS_TO_TICKS + 0.5),1); 02672 m_serial.writeMessage(&snd); 02673 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 02674 if (m_lastResult != XRV_OK) 02675 return m_lastResult; 02676 if (m_logging) 02677 m_logFile.writeMessage(&rcv); 02678 HANDLE_ERR_RESULT; 02679 02680 return m_lastResult = XRV_OK; 02681 } 02682 02683 ////////////////////////////////////////////////////////////////////////////////////////// 02684 // Set the outbound synchronization skip factor of a device. 02685 XsensResultValue Cmt3::setSyncOutSkipFactor(const uint16_t skipFactor) 02686 { 02687 CMT3LOG(__FUNCTION__ " %u\n",skipFactor); 02688 CMT3EXITLOG; 02689 02690 if (isXm()) 02691 return m_lastResult = XRV_INVALIDOPERATION; 02692 02693 Message snd(CMT_MID_REQSYNCOUTSETTINGS,3); 02694 Message rcv; 02695 02696 snd.setBusId(CMT_BID_MASTER); 02697 02698 snd.setDataByte(CMT_PARAM_SYNCOUT_SKIPFACTOR); 02699 snd.setDataShort(skipFactor,1); 02700 m_serial.writeMessage(&snd); 02701 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 02702 if (m_lastResult != XRV_OK) 02703 return m_lastResult; 02704 if (m_logging) 02705 m_logFile.writeMessage(&rcv); 02706 HANDLE_ERR_RESULT; 02707 02708 return m_lastResult = XRV_OK; 02709 } 02710 02711 ////////////////////////////////////////////////////////////////////////////////////////// 02712 // Set the outbound synchronization offset of a device. 02713 XsensResultValue Cmt3::setSyncOutOffset(const uint32_t offset) 02714 { 02715 CMT3LOG(__FUNCTION__ " %u\n", offset); 02716 CMT3EXITLOG; 02717 02718 if (isXm()) 02719 return m_lastResult = XRV_INVALIDOPERATION; 02720 02721 Message snd(CMT_MID_REQSYNCOUTSETTINGS,3); 02722 Message rcv; 02723 02724 snd.setBusId(CMT_BID_MASTER); 02725 02726 snd.setDataByte(CMT_PARAM_SYNCOUT_OFFSET); 02727 snd.setDataLong((uint32_t) (((double) offset) 02728 * CMT_SYNC_CLOCK_NS_TO_TICKS + 0.5),1); 02729 m_serial.writeMessage(&snd); 02730 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_REQSYNCOUTSETTINGSACK,0,true); 02731 if (m_lastResult != XRV_OK) 02732 return m_lastResult; 02733 if (m_logging) 02734 m_logFile.writeMessage(&rcv); 02735 HANDLE_ERR_RESULT; 02736 02737 return m_lastResult = XRV_OK; 02738 } 02739 02740 ////////////////////////////////////////////////////////////////////////////////////////// 02741 // Set the configuration mode timeout value in ms. 02742 XsensResultValue Cmt3::setTimeoutConfig(const uint32_t timeout) 02743 { 02744 CMT3LOG(__FUNCTION__ " %u\n",timeout); 02745 CMT3EXITLOG; 02746 02747 m_timeoutConf = timeout; 02748 if (!m_measuring) 02749 return m_lastResult = m_serial.setTimeout(m_timeoutConf); 02750 return m_lastResult = XRV_OK; 02751 } 02752 02753 ////////////////////////////////////////////////////////////////////////////////////////// 02754 // Set the measurement mode timeout value in ms. 02755 XsensResultValue Cmt3::setTimeoutMeasurement(const uint32_t timeout) 02756 { 02757 CMT3LOG(__FUNCTION__ " %u\n",timeout); 02758 CMT3EXITLOG; 02759 02760 m_timeoutMeas = timeout; 02761 if (m_measuring) 02762 return m_lastResult = m_serial.setTimeout(m_timeoutMeas); 02763 return m_lastResult = XRV_OK; 02764 } 02765 02766 ////////////////////////////////////////////////////////////////////////////////////////// 02767 // Retrieve the transmission delay 02768 XsensResultValue Cmt3::setTransmissionDelay(const uint16_t delay) 02769 { 02770 CMT3LOG(__FUNCTION__ " %u\n",(uint32_t) delay); 02771 CMT3EXITLOG; 02772 02773 if (isXm()) 02774 return m_lastResult = XRV_INVALIDOPERATION; 02775 02776 DO_DATA_SET_BID(CMT_MID_SETTRANSMITDELAY,CMT_LEN_TRANSMITDELAY,Short,delay,CMT_BID_MASTER); 02777 return m_lastResult = XRV_OK; 02778 } 02779 02780 ////////////////////////////////////////////////////////////////////////////////////////// 02781 // Set the dual-mode output settings of the XM 02782 XsensResultValue Cmt3::setXmOutputMode(const uint8_t mode) 02783 { 02784 CMT3LOG(__FUNCTION__ " %u\n",(uint32_t) mode); 02785 CMT3EXITLOG; 02786 02787 if (!isXm()) 02788 return m_lastResult = XRV_INVALIDOPERATION; 02789 02790 DO_DATA_SET_BID(CMT_MID_REQOPMODE,CMT_LEN_OPMODE,Byte,mode,CMT_BID_MASTER); 02791 return m_lastResult = XRV_OK; 02792 } 02793 02794 ////////////////////////////////////////////////////////////////////////////////////////// 02795 XsensResultValue Cmt3::refreshCache(const bool file) 02796 { 02797 CMT3LOG(__FUNCTION__ " %d\n",file?1:0); 02798 CMT3EXITLOG; 02799 02800 if (m_serial.isOpen() && (!file || !m_logFile.isOpen())) 02801 { 02802 // clear eMts cache 02803 for (uint32_t i = 0; i < CMT_MAX_DEVICES_PER_PORT; ++i) 02804 { 02805 CHKFREENUL(m_eMtsData[i]); 02806 } 02807 02808 // port open, go to configuration mode 02809 if (m_measuring && gotoConfig() != XRV_OK) 02810 return m_lastResult; // m_lastResult is already set by gotoConfig() 02811 02812 // now in configuration mode, read device information 02813 CMT3LOG(__FUNCTION__ " Device in configuration mode, reading device information\n"); 02814 02815 Message snd; 02816 Message rcv; 02817 02818 // all information is in the Configuration message 02819 snd.setMessageId(CMT_MID_REQCONFIGURATION); 02820 m_serial.writeMessage(&snd); 02821 if ((m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_CONFIGURATION,0,false)) != XRV_OK) 02822 return m_lastResult; 02823 if (m_logging) 02824 m_logFile.writeMessage(&rcv); 02825 m_config.readFromMessage(rcv.getMessageStart()); 02826 02827 if (m_config.m_numberOfDevices > CMT_MAX_DEVICES_PER_PORT) 02828 return m_lastResult = XRV_CONFIGCHECKFAIL; 02829 02830 m_period = m_config.m_samplingPeriod; 02831 m_skip = m_config.m_outputSkipFactor; 02832 02833 return m_lastResult = XRV_OK; 02834 } 02835 else if (m_logFile.isOpen() && (file || !m_serial.isOpen())) 02836 { 02837 // clear eMts cache 02838 for (uint32_t i = 0; i < CMT_MAX_DEVICES_PER_PORT; ++i) 02839 { 02840 CHKFREENUL(m_eMtsData[i]); 02841 } 02842 02843 // now in configuration mode, read device information 02844 CMT3LOG(__FUNCTION__ " Reading device configuration information from file\n"); 02845 02846 Message rcv; 02847 02848 if ((m_lastResult = m_logFile.readMessage(&rcv,CMT_MID_CONFIGURATION)) != XRV_OK) 02849 return m_lastResult; 02850 m_config.readFromMessage(rcv.getMessageStart()); 02851 02852 m_period = m_config.m_samplingPeriod; 02853 m_skip = m_config.m_outputSkipFactor; 02854 //CmtDeviceMode2 mode; 02855 //mode.setPeriodAndSkipFactor(m_config.m_samplingPeriod,m_config.m_outputSkipFactor); 02856 //mode.m_period = m_config.m_samplingPeriod; 02857 //mode.m_skip = m_config.m_outputSkipFactor; 02858 //m_sampleFrequency = mode.getRealSampleFrequency(); 02859 02860 return m_lastResult = XRV_OK; 02861 } 02862 else 02863 return m_lastResult = XRV_NOFILEORPORTOPEN; 02864 } 02865 02866 ////////////////////////////////////////////////////////////////////////////////////////// 02867 // Wait for a data message to arrive. 02868 XsensResultValue Cmt3::waitForDataMessage(Packet* pack) 02869 { 02870 CMT3LOGDAT(__FUNCTION__ " %p\n",pack); 02871 CMT3EXITLOGDAT; 02872 02873 m_lastResult = XRV_TIMEOUTNODATA; 02874 02875 uint32_t toEnd = (getTimeOfDay() + (uint32_t) m_timeoutMeas) % (XSENS_MS_PER_DAY); 02876 while(toEnd >= getTimeOfDay()) 02877 { 02878 m_lastResult = m_serial.waitForMessage(&pack->m_msg,CMT_MID_MTDATA,0,true); 02879 if (m_lastResult == XRV_OK) 02880 { 02881 if (m_logging) 02882 m_logFile.writeMessage(&pack->m_msg); 02883 if (pack->m_msg.getMessageId() == CMT_MID_ERROR) 02884 { 02885 m_lastHwErrorDeviceId = m_config.m_masterDeviceId; 02886 if (pack->m_msg.getDataSize() >= 2) 02887 { 02888 uint8_t biddy = pack->m_msg.getDataByte(1); 02889 getDeviceId(biddy,m_lastHwErrorDeviceId); 02890 } 02891 return m_lastResult = m_lastHwError = (XsensResultValue) pack->m_msg.getDataByte(0); 02892 } 02893 02894 pack->m_itemCount = m_config.m_numberOfDevices; 02895 for (uint16_t i = 0;i < m_config.m_numberOfDevices;++i) 02896 pack->setDataFormat(m_config.m_deviceInfo[i].m_outputMode,m_config.m_deviceInfo[i].m_outputSettings,i); 02897 pack->m_toa = timeStampNow(); 02898 if (m_useRtc) 02899 fillRtc(pack); 02900 02901 return m_lastResult = XRV_OK; 02902 } 02903 } 02904 return m_lastResult;// = XRV_TIMEOUT; 02905 } 02906 02907 ////////////////////////////////////////////////////////////////////////////////////////// 02908 XsensResultValue Cmt3::createLogFile(const char* filename, bool startLogging) 02909 { 02910 CMT3LOG(__FUNCTION__ " \"%s\" %u\n",filename?filename:"",startLogging?1:0); 02911 CMT3EXITLOG; 02912 02913 if (!m_serial.isOpen()) 02914 return m_lastResult = XRV_NOPORTOPEN; 02915 if (m_logFile.isOpen()) 02916 return m_lastResult = XRV_ALREADYOPEN; 02917 m_lastResult = m_logFile.create(filename); 02918 if (m_lastResult == XRV_OK) 02919 { 02920 m_logging = true; 02921 CmtDeviceConfiguration config; 02922 if (getConfiguration(config) == XRV_OK) 02923 { 02924 void* buffer = malloc(CMT_EMTS_SIZE*(m_config.m_numberOfDevices+1)); 02925 getEMtsData(buffer,CMT_DID_BROADCAST); 02926 free(buffer); 02927 m_logging = startLogging; 02928 } 02929 } 02930 02931 if (m_lastResult != XRV_OK) 02932 { 02933 m_logFile.closeAndDelete(); 02934 m_logging = false; 02935 } 02936 return m_lastResult; 02937 } 02938 02939 ////////////////////////////////////////////////////////////////////////////////////////// 02940 XsensResultValue Cmt3::createLogFile(const wchar_t* filename, bool startLogging) 02941 { 02942 CMT3LOG(__FUNCTION__ " \"%S\" %u\n",filename?filename:L"",startLogging?1:0); 02943 CMT3EXITLOG; 02944 02945 if (!m_serial.isOpen()) 02946 return m_lastResult = XRV_NOPORTOPEN; 02947 if (m_logFile.isOpen()) 02948 return m_lastResult = XRV_ALREADYOPEN; 02949 m_lastResult = m_logFile.create(filename); 02950 if (m_lastResult == XRV_OK) 02951 { 02952 m_logging = true; 02953 CmtDeviceConfiguration config; 02954 if (getConfiguration(config) == XRV_OK) 02955 { 02956 void* buffer = malloc(CMT_EMTS_SIZE*(m_config.m_numberOfDevices+1)); 02957 getEMtsData(buffer,CMT_DID_BROADCAST); 02958 free(buffer); 02959 m_logging = startLogging; 02960 } 02961 } 02962 02963 if (m_lastResult != XRV_OK) 02964 { 02965 m_logFile.closeAndDelete(); 02966 m_logging = false; 02967 } 02968 return m_lastResult; 02969 } 02970 02971 ////////////////////////////////////////////////////////////////////////////////////////// 02972 XsensResultValue Cmt3::closeLogFile(bool del) 02973 { 02974 CMT3LOG(__FUNCTION__ " %u\n",del?1:0); 02975 CMT3EXITLOG; 02976 02977 m_logging = false; 02978 if (!m_logFile.isOpen()) 02979 return m_lastResult = XRV_NOFILEOPEN; 02980 if (del) 02981 return m_lastResult = m_logFile.closeAndDelete(); 02982 else 02983 return m_lastResult = m_logFile.close(); 02984 } 02985 02986 ////////////////////////////////////////////////////////////////////////////////////////// 02987 bool Cmt3::isLogFileOpen(const char* filename) const 02988 { 02989 CMT3LOG(__FUNCTION__ " \"%s\"\n",filename?filename:""); 02990 02991 if (m_logFile.isOpen()) 02992 { 02993 if (filename != NULL && filename[0] != 0) 02994 { 02995 char fn[CMT_MAX_FILENAME_LENGTH]; 02996 m_logFile.getName(fn); 02997 if (_strnicmp(filename,fn,CMT_MAX_FILENAME_LENGTH) != 0) 02998 return false; 02999 } 03000 return true; 03001 } 03002 return false; 03003 } 03004 03005 ////////////////////////////////////////////////////////////////////////////////////////// 03006 bool Cmt3::isLogFileOpen(const wchar_t* filename) const 03007 { 03008 CMT3LOG(__FUNCTION__ " \"%S\"\n",filename?filename:L""); 03009 03010 if (m_logFile.isOpen()) 03011 { 03012 if (filename != NULL && filename[0] != L'\0') 03013 { 03014 wchar_t fn[CMT_MAX_FILENAME_LENGTH]; 03015 m_logFile.getName(fn); 03016 if (_wcsnicmp(filename,fn,CMT_MAX_FILENAME_LENGTH) != 0) 03017 return false; 03018 } 03019 return true; 03020 } 03021 return false; 03022 } 03023 03024 ////////////////////////////////////////////////////////////////////////////////////////// 03025 XsensResultValue Cmt3::openLogFile(const char* filename) 03026 { 03027 CMT3LOG(__FUNCTION__ " \"%s\"\n",filename?filename:""); 03028 CMT3EXITLOG; 03029 03030 m_logging = false; 03031 if (m_serial.isOpen()) 03032 return m_lastResult = XRV_INVALIDOPERATION; 03033 if (m_logFile.isOpen()) 03034 return m_lastResult = XRV_ALREADYOPEN; 03035 m_lastResult = m_logFile.open(filename,true); 03036 if (m_lastResult == XRV_OK) 03037 { 03038 // check first two bytes of file for FA FF 03039 uint8_t hdrBuf[2] = { 0,0 }; 03040 m_logFile.getCmt1f()->readData(2,hdrBuf,NULL); 03041 if (hdrBuf[0] != 0xFA || hdrBuf[1] != 0xFF) 03042 return m_lastResult = XRV_DATACORRUPT; 03043 m_logFile.getCmt1f()->setReadPos(0); 03044 03045 if (refreshCache() == XRV_OK) 03046 m_readFromFile = true; 03047 else 03048 { 03049 m_logFile.close(); 03050 m_readFromFile = false; 03051 } 03052 } 03053 return m_lastResult; 03054 } 03055 03056 ////////////////////////////////////////////////////////////////////////////////////////// 03057 XsensResultValue Cmt3::openLogFile(const wchar_t* filename) 03058 { 03059 CMT3LOG(__FUNCTION__ " \"%S\"\n",filename?filename:L""); 03060 CMT3EXITLOG; 03061 03062 m_logging = false; 03063 if (m_serial.isOpen()) 03064 return m_lastResult = XRV_INVALIDOPERATION; 03065 if (m_logFile.isOpen()) 03066 return m_lastResult = XRV_ALREADYOPEN; 03067 m_lastResult = m_logFile.open(filename,true); 03068 if (m_lastResult == XRV_OK) 03069 { 03070 // check first two bytes of file for FA FF 03071 uint8_t hdrBuf[2] = { 0,0 }; 03072 m_logFile.getCmt1f()->readData(2,hdrBuf,NULL); 03073 if (hdrBuf[0] != 0xFA || hdrBuf[1] != 0xFF) 03074 return m_lastResult = XRV_DATACORRUPT; 03075 m_logFile.getCmt1f()->setReadPos(0); 03076 03077 if (refreshCache() == XRV_OK) 03078 m_readFromFile = true; 03079 else 03080 { 03081 m_logFile.close(); 03082 m_readFromFile = false; 03083 } 03084 } 03085 return m_lastResult; 03086 } 03087 03088 ////////////////////////////////////////////////////////////////////////////////////////// 03089 XsensResultValue Cmt3::setDataSource(bool readFromFile) 03090 { 03091 CMT3LOG(__FUNCTION__ " %s\n",readFromFile?"file":"port"); 03092 CMT3EXITLOG; 03093 03094 if (readFromFile) 03095 { 03096 m_logging = false; 03097 if (m_logFile.isOpen()) 03098 { 03099 m_readFromFile = true; 03100 return m_lastResult = XRV_OK; 03101 } 03102 m_readFromFile = false; 03103 return m_lastResult = XRV_INVALIDOPERATION; 03104 } 03105 if (m_serial.isOpen()) 03106 { 03107 m_readFromFile = false; 03108 return m_lastResult = XRV_OK; 03109 } 03110 if (m_logFile.isOpen()) 03111 { 03112 m_readFromFile = true; 03113 return m_lastResult = XRV_INVALIDOPERATION; 03114 } 03115 m_readFromFile = false; 03116 return m_lastResult = XRV_NOFILEORPORTOPEN; 03117 } 03118 03119 ////////////////////////////////////////////////////////////////////////////////////////// 03120 XsensResultValue Cmt3::setLogMode(bool active) 03121 { 03122 CMT3LOG(__FUNCTION__ " %u\n",active?1:0); 03123 CMT3EXITLOG; 03124 03125 if (active && (m_readFromFile || !m_logFile.isOpen())) 03126 return m_lastResult = XRV_NOFILEOPEN; 03127 m_logging = active; 03128 return m_lastResult = XRV_OK; 03129 } 03130 03131 ////////////////////////////////////////////////////////////////////////////////////////// 03132 XsensResultValue Cmt3::resetLogFileReadPos(void) 03133 { 03134 CMT3LOG(__FUNCTION__ "\n"); 03135 CMT3EXITLOG; 03136 03137 return m_lastResult = m_logFile.setReadPosition(0); 03138 } 03139 03140 ////////////////////////////////////////////////////////////////////////////////////////// 03141 XsensResultValue Cmt3::writeMessageToLogFile(const Message& msg) 03142 { 03143 CMT3LOG(__FUNCTION__ "\n"); 03144 CMT3EXITLOG; 03145 03146 if (!m_logFile.isOpen()) 03147 return m_lastResult = XRV_NOFILEOPEN; 03148 03149 return m_lastResult = m_logFile.writeMessage(&msg); 03150 } 03151 03152 ////////////////////////////////////////////////////////////////////////////////////////// 03153 XsensResultValue Cmt3::getAvailableScenarios(CmtScenario* scenarios, const CmtDeviceId deviceId) 03154 { 03155 CMT3LOG(__FUNCTION__ " %p %08x\n",scenarios,deviceId); 03156 CMT3EXITLOG; 03157 03158 DO_DATA_REQUEST(CMT_MID_REQAVAILABLESCENARIOS); 03159 03160 char tp = 0; 03161 switch (deviceId & CMT_DID_TYPEH_MASK) 03162 { 03163 case CMT_DID_TYPEH_MTIG: 03164 tp = '6'; 03165 break; 03166 case CMT_DID_TYPEH_MTI_MTX: 03167 tp = '3'; 03168 break; 03169 } 03170 03171 for (int i = 0; i < CMT_MAX_SCENARIOS_IN_MT; ++i) 03172 { 03173 scenarios[i].m_type = rcv.getDataByte(0 + i*(1+1+CMT_LEN_SCENARIOLABEL)); 03174 scenarios[i].m_version = rcv.getDataByte(1 + i*(1+1+CMT_LEN_SCENARIOLABEL)); 03175 memcpy(scenarios[i].m_label,rcv.getDataBuffer(2 + i*(1+1+CMT_LEN_SCENARIOLABEL)),CMT_LEN_SCENARIOLABEL); 03176 scenarios[i].m_label[CMT_LEN_SCENARIOLABEL] = 0; 03177 scenarios[i].m_filterType = tp; 03178 } 03179 return m_lastResult = XRV_OK; 03180 } 03181 03182 XsensResultValue Cmt3::getScenario(uint8_t& scenarioType, uint8_t& scenarioVersion, const CmtDeviceId deviceId) 03183 { 03184 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 03185 CMT3EXITLOG; 03186 03187 DO_DATA_REQUEST(CMT_MID_REQSCENARIO); 03188 scenarioType = rcv.getDataByte(1); 03189 scenarioVersion = rcv.getDataByte(0); 03190 return m_lastResult = XRV_OK; 03191 } 03192 03193 XsensResultValue Cmt3::setScenario(const uint8_t scenarioType, const CmtDeviceId deviceId) 03194 { 03195 CMT3LOG(__FUNCTION__ " %u %08x\n",(uint32_t) scenarioType,deviceId); 03196 CMT3EXITLOG; 03197 03198 uint8_t bid = getBusIdInternal(deviceId); 03199 if (bid == CMT_BID_INVALID) 03200 return (m_lastResult = XRV_INVALIDID); 03201 03202 uint16_t scenario = (uint16_t) scenarioType; 03203 DO_DATA_SET_BID(CMT_MID_SETSCENARIO,CMT_LEN_SETSCENARIO,Short,scenario,bid); 03204 03205 if (bid == CMT_BID_BROADCAST || bid == CMT_BID_MASTER) { 03206 bid = 1; 03207 } 03208 m_config.m_deviceInfo[bid-1].m_currentScenario = scenario; // update device info 03209 //m_config.m_deviceInfo[bid-1].m_currentScenario += (uint16_t)scenarioVersion << 8; 03210 03211 return m_lastResult = XRV_OK; 03212 } 03213 03214 XsensResultValue Cmt3::getGravityMagnitude(double& magnitude, const CmtDeviceId deviceId) 03215 { 03216 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 03217 CMT3EXITLOG; 03218 03219 DO_DATA_REQUEST(CMT_MID_REQGRAVITYMAGNITUDE); 03220 magnitude = rcv.getDataFloat(0); 03221 return m_lastResult = XRV_OK; 03222 } 03223 03224 XsensResultValue Cmt3::setGravityMagnitude(const double magnitude, const CmtDeviceId deviceId) 03225 { 03226 CMT3LOG(__FUNCTION__ " %f %08x\n",magnitude,deviceId); 03227 CMT3EXITLOG; 03228 03229 DO_DATA_SET(CMT_MID_SETGRAVITYMAGNITUDE,CMT_LEN_GRAVITYMAGNITUDE,Float,(float) magnitude); 03230 return m_lastResult = XRV_OK; 03231 } 03232 03233 XsensResultValue Cmt3::getGpsLeverArm(CmtVector& arm, const CmtDeviceId deviceId) 03234 { 03235 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 03236 CMT3EXITLOG; 03237 03238 DO_DATA_REQUEST(CMT_MID_REQGPSLEVERARM); 03239 arm.m_data[0] = rcv.getDataFloat(0); 03240 arm.m_data[1] = rcv.getDataFloat(4); 03241 arm.m_data[2] = rcv.getDataFloat(8); 03242 return m_lastResult = XRV_OK; 03243 } 03244 03245 XsensResultValue Cmt3::getGpsStatus(CmtGpsStatus& status, const CmtDeviceId deviceId) 03246 { 03247 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 03248 CMT3EXITLOG; 03249 03250 DO_DATA_REQUEST(CMT_MID_REQGPSSTATUS); 03251 for (uint16_t i = 0; i < CMT_MAX_SVINFO; ++i) 03252 { 03253 status.m_svInfo[i].m_id = rcv.getDataByte(i*5+2); 03254 status.m_svInfo[i].m_navigationStatus = rcv.getDataByte(i*5+3); 03255 status.m_svInfo[i].m_signalQuality= rcv.getDataByte(i*5+4); 03256 status.m_svInfo[i].m_signalStrength = rcv.getDataByte(i*5+5); 03257 } 03258 return m_lastResult = XRV_OK; 03259 } 03260 03261 XsensResultValue Cmt3::setGpsLeverArm(const CmtVector& arm, const CmtDeviceId deviceId) 03262 { 03263 CMT3LOG(__FUNCTION__ " [%f %f %f] %08x\n",arm.m_data[0],arm.m_data[1],arm.m_data[2],deviceId); 03264 CMT3EXITLOG; 03265 03266 uint8_t bid = getBusIdInternal(deviceId); 03267 if (bid == CMT_BID_INVALID || bid == CMT_BID_BROADCAST) 03268 return (m_lastResult = XRV_INVALIDID); 03269 03270 Message snd(CMT_MID_SETGPSLEVERARM,CMT_LEN_GPSLEVERARM); 03271 Message rcv; 03272 snd.setDataFloat((float) arm.m_data[0],0); 03273 snd.setDataFloat((float) arm.m_data[1],4); 03274 snd.setDataFloat((float) arm.m_data[2],8); 03275 03276 snd.setBusId(bid); 03277 m_serial.writeMessage(&snd); 03278 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_SETGPSLEVERARMACK,0,true); 03279 if (m_lastResult != XRV_OK) 03280 return m_lastResult; 03281 if (m_logging) 03282 m_logFile.writeMessage(&rcv); 03283 if (rcv.getMessageId() == CMT_MID_ERROR) 03284 { 03285 m_lastHwErrorDeviceId = m_config.m_masterDeviceId; 03286 if (rcv.getDataSize() >= 2) 03287 { 03288 uint8_t biddy = rcv.getDataByte(1); 03289 getDeviceId(biddy,m_lastHwErrorDeviceId); 03290 } 03291 return m_lastResult = m_lastHwError = (XsensResultValue) rcv.getDataByte(); 03292 } 03293 return m_lastResult = XRV_OK; 03294 } 03295 03296 XsensResultValue Cmt3::storeXkfState(const CmtDeviceId deviceId) 03297 { 03298 CMT3LOG(__FUNCTION__ " %08x\n",deviceId); 03299 CMT3EXITLOG; 03300 03301 uint8_t bid = getBusIdInternal(deviceId); 03302 if (bid == CMT_BID_INVALID || bid == CMT_BID_BROADCAST) 03303 return (m_lastResult = XRV_INVALIDID); 03304 03305 Message snd(CMT_MID_STOREXKFSTATE,CMT_LEN_STOREXKFSTATE); 03306 Message rcv; 03307 03308 snd.setBusId(bid); 03309 m_serial.writeMessage(&snd); 03310 m_lastResult = m_serial.waitForMessage(&rcv,CMT_MID_STOREXKFSTATEACK,0,true); 03311 if (m_lastResult != XRV_OK) 03312 return m_lastResult; 03313 if (m_logging) 03314 m_logFile.writeMessage(&rcv); 03315 if (rcv.getMessageId() == CMT_MID_ERROR) 03316 { 03317 m_lastHwErrorDeviceId = m_config.m_masterDeviceId; 03318 if (rcv.getDataSize() >= 2) 03319 { 03320 uint8_t biddy = rcv.getDataByte(1); 03321 getDeviceId(biddy,m_lastHwErrorDeviceId); 03322 } 03323 return m_lastResult = m_lastHwError = (XsensResultValue) rcv.getDataByte(); 03324 } 03325 return m_lastResult = XRV_OK; 03326 } 03327 } // end of xsens namespace