6 #include "../datatypes/EvalCaseResult.hpp"
7 #include "../tools/errorhandler.hpp"
22 std::string ipAddress,
31 m_deviceId = deviceId;
32 m_ipAddress = ipAddress;
33 m_portNumber = portNumber;
34 m_weWantFieldData = weWantFieldData;
35 m_weWantScanData = weWantScanData;
36 m_readOnlyMode = readOnlyMode;
55 disconnectFunction, obj);
60 printInfoMessage(
"LdmrsSopasLayer::init: SopasBase was initialized successfully.", m_beVerbose);
64 printError(
"LdmrsSopasLayer::init: Failed, aborting!");
75 printInfoMessage(
"LdmrsSopasLayer::init: Connected to scanner successfully.", m_beVerbose);
79 printError(
"LdmrsSopasLayer::init: Failed to connect to scanner, aborting!");
84 if (m_weWantFieldData ==
true)
87 printInfoMessage(
"LdmrsSopasLayer::init: Reading current field configuration.", m_beVerbose);
88 success = action_readFields();
91 printInfoMessage(
"LdmrsSopasLayer::init: Successfully read the field configuration (" +
92 ::
toString(m_fields.getFields().size()) +
" fields).", m_beVerbose);
98 m_manager->setDeviceData(f);
103 printError(
"LdmrsSopasLayer::init: Failed to read the field configuration, aborting!");
108 printInfoMessage(
"LdmrsSopasLayer::init: Reading current eval case configuration.", m_beVerbose);
109 success = action_readEvalCases();
112 printInfoMessage(
"LdmrsSopasLayer::init: Successfully read the eval cases (" +
113 ::
toString(m_evalCases.getEvalCases().size()) +
" cases).", m_beVerbose);
119 m_manager->setDeviceData(e);
124 printError(
"LdmrsSopasLayer::init: Failed to read the eval cases, aborting!");
130 printInfoMessage(
"LdmrsSopasLayer::init: Skipping field configuration as we want no field data.", m_beVerbose);
141 bool beVerboseHere = m_beVerbose;
149 if (m_weWantFieldData ==
true)
151 printInfoMessage(
"LdmrsSopasLayer::run: Now subscribing to EvalCaseResults.", beVerboseHere);
152 result = action_subscribeEvalCaseResults();
156 printError(
"LdmrsSopasLayer::run: Failed to subscribe to EvalCaseResults, aborting.");
159 printInfoMessage(
"LdmrsSopasLayer::run: Subscription to EvalCaseResults was successful.", beVerboseHere);
164 if (m_weWantScanData ==
true)
167 printInfoMessage(
"LdmrsSopasLayer::run: Now subscribing to scan data.", beVerboseHere);
168 result = action_subscribeScanData();
172 printError(
"LdmrsSopasLayer::run: Failed to subscribe to scan data, aborting.");
175 printInfoMessage(
"LdmrsSopasLayer::run: Subscription to scan data was successful.", beVerboseHere);
188 bool beVerboseHere = m_beVerbose;
191 printInfoMessage(
"LdmrsSopasLayer::action_flashFieldParameters: Called.", beVerboseHere);
193 if (isConnected() ==
false)
195 printWarning(
"LdmrsSopasLayer::action_flashFieldParameters: LD-MRS not connected - aborting.");
201 UINT8 parameterBuffer[128];
202 UINT16 parameterBufferLen = 0;
204 result = invokeMethod(index_meth_FlashFieldParameters, parameterBuffer, parameterBufferLen, answer);
206 if ((result ==
true) && (answer != NULL) && (answer->
isValid() ==
true) && (answer->
size() > 0))
210 UINT8 success = buffer[0];
214 m_isLoggedIn =
false;
216 printError(
"LdmrsSopasLayer::action_flashFieldParameters: FlashFieldPara command was not successful!");
223 printInfoMessage(
"LdmrsSopasLayer::action_flashFieldParameters: Field parameters flashed successfully.", beVerboseHere);
234 printInfoMessage(
"LdmrsSopasLayer::action_flashFieldParameters: All done, leaving.", beVerboseHere);
244 bool beVerboseHere = m_beVerbose;
247 printInfoMessage(
"LdmrsSopasLayer::action_flashMrsParameters: Called.", beVerboseHere);
249 if (isConnected() ==
false)
251 printWarning(
"LdmrsSopasLayer::action_flashMrsParameters: LD-MRS not connected - aborting.");
257 UINT8 parameterBuffer[128];
258 UINT16 parameterBufferLen = 0;
260 result = invokeMethod(index_meth_MthdFlashLUXParameters, parameterBuffer, parameterBufferLen, answer);
262 if ((result ==
true) && (answer != NULL) && (answer->
isValid() ==
true) && (answer->
size() > 0))
266 UINT8 success = buffer[0];
270 m_isLoggedIn =
false;
272 printError(
"LdmrsSopasLayer::action_flashMrsParameters: FlashLUXPara command was not successful!");
279 printInfoMessage(
"LdmrsSopasLayer::action_flashMrsParameters: MRS parameters flashed successfully.", beVerboseHere);
289 printInfoMessage(
"LdmrsSopasLayer::action_flashMrsParameters: All done, leaving.", beVerboseHere);
302 bool beVerboseHere = m_beVerbose;
306 printInfoMessage(
"LdmrsSopasLayer::action_login: Trying to log in as authorized client.", beVerboseHere);
310 if (isConnected() ==
true)
312 const static UINT32 passwordHash_LDMRS = 0xF4724744;
316 UINT8 parameterBuffer[128];
317 UINT16 parameterBufferLen = 0;
319 colab::addIntegerToBuffer<INT8>(parameterBuffer, parameterBufferLen, level);
320 colab::addIntegerToBuffer<UINT32>(parameterBuffer, parameterBufferLen, passwordHash_LDMRS);
322 result = invokeMethod(index_meth_SetAccessMode, parameterBuffer, parameterBufferLen, answer);
324 if ((result ==
true) && (answer != NULL) && (answer->
isValid() ==
true) && (answer->
size() > 0))
328 UINT8 success = buffer[0];
332 m_isLoggedIn =
false;
334 printError(
"LdmrsSopasLayer::action_login: Login was not successful!");
341 printInfoMessage(
"LdmrsSopasLayer::action_login: Login was successful.", beVerboseHere);
353 printWarning(
"LdmrsSopasLayer::action_login: LD-MRS not connected - cannot login.");
366 bool beVerboseHere = m_beVerbose;
370 printInfoMessage(
"LdmrsSopasLayer::action_logout: Logging out now.", beVerboseHere);
374 if (isConnected() ==
true)
376 const static UINT32 passwordHash_LDMRS = 0x00000000;
380 UINT8 parameterBuffer[128];
381 UINT16 parameterBufferLen = 0;
383 colab::addIntegerToBuffer<INT8>(parameterBuffer, parameterBufferLen, level);
384 colab::addIntegerToBuffer<UINT32>(parameterBuffer, parameterBufferLen, passwordHash_LDMRS);
386 result = invokeMethod(index_meth_SetAccessMode, parameterBuffer, parameterBufferLen, answer);
388 if ((result ==
true) && (answer != NULL) && (answer->
isValid() ==
true) && (answer->
size() > 0))
392 UINT8 success = buffer[0];
397 printError(
"LdmrsSopasLayer::action_logout: Logout was not successful!");
402 m_isLoggedIn =
false;
404 printInfoMessage(
"LdmrsSopasLayer::action_logout: Logout was successful.", beVerboseHere);
416 printWarning(
"LdmrsSopasLayer::action_logout: LD-MRS not connected - cannot log out, aborting.");
432 if (isConnected() ==
false)
434 printError(
"LdmrsSopasLayer::action_subscribeEvalCaseResults: LD-MRS not connected, aborting!");
438 result = registerEvent((
UINT16)(index_event_aEvalCaseResult));
442 m_fieldEventIsRegistered =
true;
446 printError(
"LdmrsSopasLayer::action_subscribeEvalCaseResults: Failed to subscribe, aborting!");
458 bool result = unregisterEvent((
UINT16)(index_event_aEvalCaseResult));
462 m_fieldEventIsRegistered =
false;
466 printError(
"LdmrsSopasLayer::action_unSubscribeEvalCases: Failed to un-subscribe, aborting!");
480 bool beVerboseHere = m_beVerbose;
482 printInfoMessage(
"LdmrsSopasLayer::action_subscribeScanData: Called.", beVerboseHere);
487 if (isConnected() ==
false)
489 printError(
"LdmrsSopasLayer::action_subscribeScanData: LD-MRS not connected, aborting!");
493 result = registerEvent((
UINT16)(index_event_ScanDataMonitor));
497 m_scanEventIsRegistered =
true;
501 printError(
"LdmrsSopasLayer::action_subscribeScanData: Failed to subscribe, aborting!");
504 printInfoMessage(
"LdmrsSopasLayer::action_subscribeScanData: Done, leaving.", beVerboseHere);
515 bool result = unregisterEvent((
UINT16)(index_event_ScanDataMonitor));
519 m_scanEventIsRegistered =
false;
523 printError(
"LdmrsSopasLayer::action_unSubscribeScanData: Failed to un-subscribe, aborting!");
535 bool success = readVariable(index_var_ScanConfig, answer);
537 if (success && answer != NULL && answer->
size() > 0)
543 switch (scanFreqEnum)
582 bool success = readVariable(index_var_evalCaseParam, answer);
586 m_evalCases = colaB_evalCaseDecoder(answer);
602 bool beVerboseHere = m_beVerbose;
605 printInfoMessage(
"LdmrsSopasLayer::colaB_evalCaseDecoder: Called.", beVerboseHere);
609 if (answer != NULL && answer->
size() > 0)
616 for (
UINT16 i = 0; i < arrayLength; ++i)
645 std::string name = std::string((
char *)bufferPos, nameLength);
646 bufferPos += nameLength;
648 printInfoMessage(
"LdmrsSopasLayer::colaB_evalCaseDecoder: Decoding EvalCase with the name " +
649 name +
". Inputs: " + ::
toHexString(inputs) +
".", beVerboseHere);
652 std::string comment = std::string((
char*)bufferPos, commentLength);
653 bufferPos += commentLength,
656 evalCases.
add(evalCasePtr);
672 bool beVerboseHere = m_beVerbose;
675 printInfoMessage(
"LdmrsSopasLayer::colaB_evalCaseEncoder: Called.", m_beVerbose);
680 BYTE* bufferPos = buffer;
687 for (
UINT16 i = 0; i < arrayLength; i++)
691 printInfoMessage(
"LdmrsSopasLayer::colaB_evalCaseEncoder: Encoding EvalCase with the name " +
708 if (resultNegation ==
true)
737 if (distDependent ==
true)
786 ::
toString(len) +
" bytes.", beVerboseHere);
800 bool beVerboseHere = m_beVerbose;
803 printInfoMessage(
"LdmrsSopasLayer::action_writeField: Called for field " +
toString(fieldNum) +
".", beVerboseHere);
808 printError(
"LdmrsSopasLayer::action_writeField: FieldNum must be 0..15, but is " +
toString(fieldNum) +
", aborting!");
815 BYTE* buffer =
new BYTE[bufferSize];
816 usedBufferLen = colaB_fieldEncoder(buffer, para);
819 result = writeVariable(index_var_field000 + fieldNum, buffer, usedBufferLen);
824 printError(
"LdmrsSopasLayer::action_writeField: Failed to write field " +
toString(fieldNum) +
", aborting!");
829 printInfoMessage(
"LdmrsSopasLayer::action_writeField: All done, leaving.", beVerboseHere);
841 bool beVerboseHere = m_beVerbose;
849 printError(
"LdmrsSopasLayer::action_writeEvalCases: The MRS can only handle up to 16 eval cases, aborting!");
856 BYTE* buffer =
new BYTE[bufferSize];
857 usedBufferLen = colaB_evalCaseEncoder(buffer, evalCases);
860 result = writeVariable(index_var_evalCaseParam, buffer, usedBufferLen);
865 printError(
"LdmrsSopasLayer::action_writeEvalCases: Failed to write eval cases, aborting!");
870 printInfoMessage(
"LdmrsSopasLayer::action_writeEvalCases: All done, leaving.", beVerboseHere);
909 for (
UINT16 i = 0; i < MAX_NUM_OF_FIELDS; ++i)
912 success = readVariable(index_var_field000 + i, answer);
914 if ((success ==
true) &&
916 (answer->
size() > 0))
921 if (fieldPtr != NULL)
923 m_fields.add(fieldPtr);
940 return ((
double)angle / 32.0) *
deg2rad;
951 bool beVerboseHere = m_beVerbose;
957 if ((answer != NULL) && (answer->
size() > 0))
980 printInfoMessage(
"LdmrsSopasLayer::colaB_fieldDecoder: Found segmented field.", beVerboseHere);
988 for (
UINT8 i = 0; i < arrayLength; ++i)
996 toString(endDist) +
".", beVerboseHere);
1024 printInfoMessage(
"LdmrsSopasLayer::colaB_fieldDecoder: Found rectangular field.", beVerboseHere);
1030 refPointAngle = -refPointAngle;
1035 rotAngle = -rotAngle;
1039 printInfoMessage(
"LdmrsSopasLayer::colaB_fieldDecoder: refPointDist is " +
toString(refPointDist) +
".", beVerboseHere);
1040 printInfoMessage(
"LdmrsSopasLayer::colaB_fieldDecoder: refPointAngle is " +
toString(-refPointAngle) +
".", beVerboseHere);
1041 printInfoMessage(
"LdmrsSopasLayer::colaB_fieldDecoder: rotAngle is " +
toString(rotAngle, 2) +
".", beVerboseHere);
1049 rect->
setWidth((
double) width / 1000.);
1050 rect->
setLength((
double) length / 1000.);
1061 printError(
"LdmrsSopasLayer::colaB_fieldDecoder: Found radial field, but the LD-MRS does not support radial fields!");
1069 printError(
"LdmrsSopasLayer::colaB_fieldDecoder: Found dynamic field, but the LD-MRS does not support dynamic fields!");
1076 printInfoMessage(
"LdmrsSopasLayer::colaB_fieldDecoder: Field version number= " +
toString(versionNumber) +
".", beVerboseHere);
1079 if (fieldNameLength > 0)
1084 printInfoMessage(
"LdmrsSopasLayer::colaB_fieldDecoder: Field name= " + fieldName +
".", beVerboseHere);
1089 if (commentLength > 0)
1113 bool beVerboseHere = m_beVerbose;
1114 beVerboseHere =
true;
1117 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Called. Decoding SOPAS frame with length=" +
1121 if (m_weWantScanData ==
false)
1127 std::string receivedName;
1131 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Reading variable index.", beVerboseHere);
1134 if (receiveIndex != index_event_ScanDataMonitor)
1136 printError(
"LdmrsSopasLayer::scanDataDecoder: This is not a scan data message, aborting!");
1141 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: This is a scan data message.", beVerboseHere);
1145 m_scanEventIsRegistered =
true;
1149 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Version number=" + ::
toString(versionNumber) +
".", beVerboseHere);
1153 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Logical number of the device=" + ::
toString(logicalNumber) +
".", beVerboseHere);
1155 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Serial number of the device=" + ::
toString(serialNumber) +
".", beVerboseHere);
1161 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Telegram count=" + ::
toString(telegramCount) +
".", beVerboseHere);
1165 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: System time scan=" + ::
toString(systemTimeScan) +
".", beVerboseHere);
1167 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: System time transmit=" + ::
toString(systemTimeTransmit) +
".", beVerboseHere);
1171 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Output state=" + ::
toString(outputState) +
".", beVerboseHere);
1175 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Scan frequency=" + ::
doubleToString(
double(scanFrequency) / 256.0, 2) +
" Hz.", beVerboseHere);
1177 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Measurement frequency=" + ::
doubleToString(
double(measurementFrequency) / 10.0, 1) +
" kHz.", beVerboseHere);
1181 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Number of encoder blocks=" + ::
toString(numOfEncoders) +
".", beVerboseHere);
1182 for (
UINT16 i = 0; i<numOfEncoders; i++)
1185 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Encoder position=" + ::
toString(encoderPos) +
" increments.", beVerboseHere);
1187 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Encoder speed=" + ::
toString(encoderSpeed) +
" inc/mm.", beVerboseHere);
1192 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Number of 16-bit data channels=" + ::
toString(numOf16BitDataChannels) +
".", beVerboseHere);
1197 vAngles[0] = -1.6 * 0.75 *
deg2rad;
1198 vAngles[1] = -1.6 * 0.25 *
deg2rad;
1199 vAngles[2] = 1.6 * 0.25 *
deg2rad;
1200 vAngles[3] = 1.6 * 0.75 *
deg2rad;
1205 for (
UINT16 i = 0; i<numOf16BitDataChannels; i++)
1209 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Content type=" + contentType +
".", beVerboseHere);
1217 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Angular resolution=" + ::
doubleToString(
double(angularResolution)/10000.0, 2) +
".", beVerboseHere);
1220 UINT16 layer = contentType.c_str()[4] -
'A';
1221 UINT16 echo = contentType.c_str()[5] -
'1';
1224 printError(
"LdmrsSopasLayer::scanDataDecoder: We have decoded an invalid layer value of " +
toString(layer) +
", allowed is 0..3.");
1229 printError(
"LdmrsSopasLayer::scanDataDecoder: We have decoded an invalid echo value of " +
toString(echo) +
", allowed is 0..2.");
1235 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Number of 16-bit data=" + ::
toString(numOf16BitData) +
".", beVerboseHere);
1236 for (
UINT16 d = 0; d<numOf16BitData; d++)
1243 if ((data > 0) && (data != 0xFFFF))
1249 double hAngle = ((startAngle + d * angularResolution) / 10000.0) *
deg2rad;
1252 double dist = (double(data) * scaleFactor) / 1000.0;
1255 newPoint.
setPolar (dist, hAngle, vAngles[layer]);
1269 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Number of 8-bit data channels=" + ::
toString(numOf8BitDataChannels) +
".", beVerboseHere);
1273 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Number of position blocks=" + ::
toString(numOfPositionBlocks) +
".", beVerboseHere);
1274 if (numOfPositionBlocks == 1)
1294 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Number of device names=" + ::
toString(numOfDeviceNames) +
".", beVerboseHere);
1295 if (numOfDeviceNames == 1)
1298 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Device name string length=" + ::
toString(deviceNameStringLen) +
".", beVerboseHere);
1299 if (deviceNameStringLen > 16)
1301 printError(
"LdmrsSopasLayer::scanDataDecoder: We have decoded an invalid device name string length of " +
1302 toString(deviceNameStringLen) +
", allowed is 0..16.");
1305 std::string deviceName =
memread_string(bufferPos, deviceNameStringLen);
1310 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Number of comment blocks=" + ::
toString(numOfCommentBlocks) +
".", beVerboseHere);
1311 if (numOfCommentBlocks == 1)
1314 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Comment string length=" + ::
toString(commentStringLen) +
".", beVerboseHere);
1315 if (commentStringLen > 128)
1317 printError(
"LdmrsSopasLayer::scanDataDecoder: We have decoded an invalid comment string length of " +
1318 toString(commentStringLen) +
", allowed is 0..128.");
1321 std::string commentString =
memread_string(bufferPos, commentStringLen);
1348 start.
set(
double(systemTimeScan) / 1000000.0);
1349 end.
set((
double(systemTimeScan) / 1000000.0) + (1.0 / (
double(scanFrequency) / 256.0)));
1353 double yawAngle, pitchAngle, rollAngle, offsetX, offsetY, offsetZ;
1360 Position3D mp(yawAngle, pitchAngle, rollAngle, offsetX, offsetY, offsetZ);
1366 m_manager->setDeviceData(scan);
1369 printInfoMessage(
"LdmrsSopasLayer::scanDataDecoder: Done, leaving.", beVerboseHere);
1379 printInfoMessage(
"LdmrsSopasLayer::evalCaseResultDecoder: Called. Decoding SOPAS frame with length=" +
1382 if (m_weWantFieldData ==
true)
1384 std::string receivedName;
1392 printInfoMessage(
"LdmrsSopasLayer::evalCaseResultDecoder: Reading variable index.", m_beVerbose);
1395 if (receiveIndex != index_event_aEvalCaseResult)
1397 printError(
"LdmrsSopasLayer::evalCaseResultDecoder: This is not an eval case message, aborting!");
1402 printInfoMessage(
"LdmrsSopasLayer::evalCaseResultDecoder: This is an eval case message.", m_beVerbose);
1406 m_fieldEventIsRegistered =
true;
1411 printInfoMessage(
"LdmrsSopasLayer::evalCaseResultDecoder: This frame contains " + ::
toString(cases) +
" cases to decode.", m_beVerbose);
1414 for (
UINT16 i = 0; i < cases; i++)
1428 switch (caseResultMRS)
1432 resTxt =
"dont_care";
1446 resTxt =
"detecting";
1468 printInfoMessage(
"LdmrsSopasLayer::evalCaseResultDecoder: CaseResult is <" + resTxt +
">.", m_beVerbose);
1515 evalCases->
add(result);
1519 if ((evalCases->
size() > 0) &&
1520 ((*evalCases) != m_lastEvalCaseResults))
1522 m_lastEvalCaseResults = *evalCases;
1523 m_manager->setDeviceData((
BasicData*)evalCases);
1528 printWarning(
"LdmrsSopasLayer::evalCaseResultDecoder: Received eval case, but we do not want to listen to eval cases!");
1530 unregisterEvent(index_event_aEvalCaseResult);
1552 measureList.
m_list.push_back(meas);
1556 measureList.
m_list.push_back(meas);
1560 measureList.
m_list.push_back(meas);
1564 measureList.
m_list.push_back(meas);
1568 measureList.
m_list.push_back(meas);
1572 measureList.
m_list.push_back(meas);
1608 return sensorStateInfo;
1619 bool beVerboseHere = m_beVerbose;
1623 BYTE* bufferOrg = buffer;
1645 printInfoMessage(
"LdmrsSopasLayer::colaB_fieldEncoder: Writing a segmented field.", beVerboseHere);
1670 double startDist = seg->
getPoints().at(p).getStartDist();
1675 printInfoMessage(
"LdmrsSopasLayer::colaB_fieldEncoder: StartDist = invalid.", beVerboseHere);
1684 printInfoMessage(
"LdmrsSopasLayer::colaB_fieldEncoder: StartDist = " +
toString(startDistInt) +
".", beVerboseHere);
1688 double endDist = seg->
getPoints().at(p).getEndDist();
1693 printInfoMessage(
"LdmrsSopasLayer::colaB_fieldEncoder: EndDist = invalid.", beVerboseHere);
1715 printInfoMessage(
"LdmrsSopasLayer::colaB_fieldEncoder: Writing rectangular field.", beVerboseHere);
1722 refPointAngle = -refPointAngle;
1731 rotAngle = -rotAngle;
1784 printInfoMessage(
"LdmrsSopasLayer::colaB_fieldEncoder: Encoded " +
toString(len) +
" bytes. All done, leaving.", beVerboseHere);