00001
00002
00003
00004
00005 #include "LdmrsSopasLayer.hpp"
00006 #include "../datatypes/EvalCaseResult.hpp"
00007 #include "../tools/errorhandler.hpp"
00008
00009 namespace devices
00010 {
00011
00012 using namespace datatypes;
00013
00014
00015
00016
00017
00018
00019
00020 LdmrsSopasLayer::LdmrsSopasLayer(Manager* manager,
00021 const UINT8 deviceId,
00022 std::string ipAddress,
00023 UINT16 portNumber,
00024 bool weWantFieldData,
00025 bool weWantScanData,
00026 bool readOnlyMode)
00027 {
00028 m_beVerbose = false;
00029
00030 m_manager = manager;
00031 m_deviceId = deviceId;
00032 m_ipAddress = ipAddress;
00033 m_portNumber = portNumber;
00034 m_weWantFieldData = weWantFieldData;
00035 m_weWantScanData = weWantScanData;
00036 m_readOnlyMode = readOnlyMode;
00037 }
00038
00039
00040
00041 LdmrsSopasLayer::~LdmrsSopasLayer()
00042 {
00043 }
00044
00045
00046
00047 bool LdmrsSopasLayer::init(Tcp::DisconnectFunction disconnectFunction, void* obj)
00048 {
00049 bool success = SopasBase::init(CoLa_B,
00050 m_ipAddress,
00051 m_portNumber,
00052 m_weWantScanData,
00053 m_weWantFieldData,
00054 m_readOnlyMode,
00055 disconnectFunction, obj);
00056
00057 if (success == true)
00058 {
00059
00060 printInfoMessage("LdmrsSopasLayer::init: SopasBase was initialized successfully.", m_beVerbose);
00061 }
00062 else
00063 {
00064 printError("LdmrsSopasLayer::init: Failed, aborting!");
00065 return false;
00066 }
00067
00068
00069
00070
00071 success = connect();
00072 if (success == true)
00073 {
00074
00075 printInfoMessage("LdmrsSopasLayer::init: Connected to scanner successfully.", m_beVerbose);
00076 }
00077 else
00078 {
00079 printError("LdmrsSopasLayer::init: Failed to connect to scanner, aborting!");
00080 return false;
00081 }
00082
00083
00084 if (m_weWantFieldData == true)
00085 {
00086
00087 printInfoMessage("LdmrsSopasLayer::init: Reading current field configuration.", m_beVerbose);
00088 success = action_readFields();
00089 if (success == true)
00090 {
00091 printInfoMessage("LdmrsSopasLayer::init: Successfully read the field configuration (" +
00092 ::toString(m_fields.getFields().size()) + " fields).", m_beVerbose);
00093
00094
00095 Fields* f = new Fields;
00096 *f = m_fields;
00097 f->setSourceId(m_deviceId);
00098 m_manager->setDeviceData(f);
00099 }
00100 else
00101 {
00102
00103 printError("LdmrsSopasLayer::init: Failed to read the field configuration, aborting!");
00104 return false;
00105 }
00106
00107
00108 printInfoMessage("LdmrsSopasLayer::init: Reading current eval case configuration.", m_beVerbose);
00109 success = action_readEvalCases();
00110 if (success == true)
00111 {
00112 printInfoMessage("LdmrsSopasLayer::init: Successfully read the eval cases (" +
00113 ::toString(m_evalCases.getEvalCases().size()) + " cases).", m_beVerbose);
00114
00115
00116 EvalCases* e = new EvalCases;
00117 *e = m_evalCases;
00118 e->setSourceId(m_deviceId);
00119 m_manager->setDeviceData(e);
00120 }
00121 else
00122 {
00123
00124 printError("LdmrsSopasLayer::init: Failed to read the eval cases, aborting!");
00125 return false;
00126 }
00127 }
00128 else
00129 {
00130 printInfoMessage("LdmrsSopasLayer::init: Skipping field configuration as we want no field data.", m_beVerbose);
00131 }
00132
00133 return success;
00134 }
00135
00136
00137
00138
00139 bool LdmrsSopasLayer::run()
00140 {
00141 bool beVerboseHere = m_beVerbose;
00142
00143
00144 printInfoMessage("LdmrsSopasLayer::run: Called.", beVerboseHere);
00145
00146 bool result = false;
00147
00148
00149 if (m_weWantFieldData == true)
00150 {
00151 printInfoMessage("LdmrsSopasLayer::run: Now subscribing to EvalCaseResults.", beVerboseHere);
00152 result = action_subscribeEvalCaseResults();
00153 if (result == false)
00154 {
00155
00156 printError("LdmrsSopasLayer::run: Failed to subscribe to EvalCaseResults, aborting.");
00157 return false;
00158 }
00159 printInfoMessage("LdmrsSopasLayer::run: Subscription to EvalCaseResults was successful.", beVerboseHere);
00160 }
00161
00162
00163
00164 if (m_weWantScanData == true)
00165 {
00166
00167 printInfoMessage("LdmrsSopasLayer::run: Now subscribing to scan data.", beVerboseHere);
00168 result = action_subscribeScanData();
00169 if (result == false)
00170 {
00171
00172 printError("LdmrsSopasLayer::run: Failed to subscribe to scan data, aborting.");
00173 return false;
00174 }
00175 printInfoMessage("LdmrsSopasLayer::run: Subscription to scan data was successful.", beVerboseHere);
00176
00177 }
00178
00179 return true;
00180 }
00181
00182
00183
00184
00185
00186 bool LdmrsSopasLayer::action_flashFieldParameters()
00187 {
00188 bool beVerboseHere = m_beVerbose;
00189
00190
00191 printInfoMessage("LdmrsSopasLayer::action_flashFieldParameters: Called.", beVerboseHere);
00192
00193 if (isConnected() == false)
00194 {
00195 printWarning("LdmrsSopasLayer::action_flashFieldParameters: LD-MRS not connected - aborting.");
00196 return false;
00197 }
00198
00199 bool result = false;
00200 SopasAnswer* answer = NULL;
00201 UINT8 parameterBuffer[128];
00202 UINT16 parameterBufferLen = 0;
00203
00204 result = invokeMethod(index_meth_FlashFieldParameters, parameterBuffer, parameterBufferLen, answer);
00205
00206 if ((result == true) && (answer != NULL) && (answer->isValid() == true) && (answer->size() > 0))
00207 {
00208
00209 BYTE* buffer = answer->getBuffer();
00210 UINT8 success = buffer[0];
00211 if (success == 0)
00212 {
00213
00214 m_isLoggedIn = false;
00215 result = false;
00216 printError("LdmrsSopasLayer::action_flashFieldParameters: FlashFieldPara command was not successful!");
00217 }
00218 else
00219 {
00220
00221 m_isLoggedIn = true;
00222 result = true;
00223 printInfoMessage("LdmrsSopasLayer::action_flashFieldParameters: Field parameters flashed successfully.", beVerboseHere);
00224 }
00225 }
00226
00227
00228 if (answer != NULL)
00229 {
00230 delete answer;
00231 answer = NULL;
00232 }
00233
00234 printInfoMessage("LdmrsSopasLayer::action_flashFieldParameters: All done, leaving.", beVerboseHere);
00235 return result;
00236 }
00237
00238
00239
00240
00241
00242 bool LdmrsSopasLayer::action_flashMrsParameters()
00243 {
00244 bool beVerboseHere = m_beVerbose;
00245
00246
00247 printInfoMessage("LdmrsSopasLayer::action_flashMrsParameters: Called.", beVerboseHere);
00248
00249 if (isConnected() == false)
00250 {
00251 printWarning("LdmrsSopasLayer::action_flashMrsParameters: LD-MRS not connected - aborting.");
00252 return false;
00253 }
00254
00255 bool result = false;
00256 SopasAnswer* answer = NULL;
00257 UINT8 parameterBuffer[128];
00258 UINT16 parameterBufferLen = 0;
00259
00260 result = invokeMethod(index_meth_MthdFlashLUXParameters, parameterBuffer, parameterBufferLen, answer);
00261
00262 if ((result == true) && (answer != NULL) && (answer->isValid() == true) && (answer->size() > 0))
00263 {
00264
00265 BYTE* buffer = answer->getBuffer();
00266 UINT8 success = buffer[0];
00267 if (success == 0)
00268 {
00269
00270 m_isLoggedIn = false;
00271 result = false;
00272 printError("LdmrsSopasLayer::action_flashMrsParameters: FlashLUXPara command was not successful!");
00273 }
00274 else
00275 {
00276
00277 m_isLoggedIn = true;
00278 result = true;
00279 printInfoMessage("LdmrsSopasLayer::action_flashMrsParameters: MRS parameters flashed successfully.", beVerboseHere);
00280 }
00281 }
00282
00283
00284 if (answer != NULL)
00285 {
00286 delete answer;
00287 }
00288
00289 printInfoMessage("LdmrsSopasLayer::action_flashMrsParameters: All done, leaving.", beVerboseHere);
00290
00291 return result;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300 bool LdmrsSopasLayer::action_login()
00301 {
00302 bool beVerboseHere = m_beVerbose;
00303
00304
00305
00306 printInfoMessage("LdmrsSopasLayer::action_login: Trying to log in as authorized client.", beVerboseHere);
00307
00308 bool result = false;
00309
00310 if (isConnected() == true)
00311 {
00312 const static UINT32 passwordHash_LDMRS = 0xF4724744;
00313 SopasAnswer* answer = NULL;
00314
00315 INT8 level = 3;
00316 UINT8 parameterBuffer[128];
00317 UINT16 parameterBufferLen = 0;
00318
00319 colab::addIntegerToBuffer<INT8>(parameterBuffer, parameterBufferLen, level);
00320 colab::addIntegerToBuffer<UINT32>(parameterBuffer, parameterBufferLen, passwordHash_LDMRS);
00321
00322 result = invokeMethod(index_meth_SetAccessMode, parameterBuffer, parameterBufferLen, answer);
00323
00324 if ((result == true) && (answer != NULL) && (answer->isValid() == true) && (answer->size() > 0))
00325 {
00326
00327 BYTE* buffer = answer->getBuffer();
00328 UINT8 success = buffer[0];
00329 if (success == 0)
00330 {
00331
00332 m_isLoggedIn = false;
00333 result = false;
00334 printError("LdmrsSopasLayer::action_login: Login was not successful!");
00335 }
00336 else
00337 {
00338
00339 m_isLoggedIn = true;
00340 result = true;
00341 printInfoMessage("LdmrsSopasLayer::action_login: Login was successful.", beVerboseHere);
00342 }
00343 }
00344
00345
00346 if (answer != NULL)
00347 {
00348 delete answer;
00349 }
00350 }
00351 else
00352 {
00353 printWarning("LdmrsSopasLayer::action_login: LD-MRS not connected - cannot login.");
00354 }
00355
00356 return result;
00357 }
00358
00359
00360
00361
00362
00363 bool LdmrsSopasLayer::action_logout()
00364 {
00365
00366 bool beVerboseHere = m_beVerbose;
00367
00368
00369
00370 printInfoMessage("LdmrsSopasLayer::action_logout: Logging out now.", beVerboseHere);
00371
00372 bool result = false;
00373
00374 if (isConnected() == true)
00375 {
00376 const static UINT32 passwordHash_LDMRS = 0x00000000;
00377 SopasAnswer* answer = NULL;
00378
00379 INT8 level = 1;
00380 UINT8 parameterBuffer[128];
00381 UINT16 parameterBufferLen = 0;
00382
00383 colab::addIntegerToBuffer<INT8>(parameterBuffer, parameterBufferLen, level);
00384 colab::addIntegerToBuffer<UINT32>(parameterBuffer, parameterBufferLen, passwordHash_LDMRS);
00385
00386 result = invokeMethod(index_meth_SetAccessMode, parameterBuffer, parameterBufferLen, answer);
00387
00388 if ((result == true) && (answer != NULL) && (answer->isValid() == true) && (answer->size() > 0))
00389 {
00390
00391 BYTE* buffer = answer->getBuffer();
00392 UINT8 success = buffer[0];
00393 if (success == 0)
00394 {
00395
00396 result = false;
00397 printError("LdmrsSopasLayer::action_logout: Logout was not successful!");
00398 }
00399 else
00400 {
00401
00402 m_isLoggedIn = false;
00403 result = true;
00404 printInfoMessage("LdmrsSopasLayer::action_logout: Logout was successful.", beVerboseHere);
00405 }
00406 }
00407
00408
00409 if (answer != NULL)
00410 {
00411 delete answer;
00412 }
00413 }
00414 else
00415 {
00416 printWarning("LdmrsSopasLayer::action_logout: LD-MRS not connected - cannot log out, aborting.");
00417 }
00418
00419 return result;
00420 }
00421
00422
00423
00424
00425
00426
00427 bool LdmrsSopasLayer::action_subscribeEvalCaseResults()
00428 {
00429
00430 bool result = false;
00431
00432 if (isConnected() == false)
00433 {
00434 printError("LdmrsSopasLayer::action_subscribeEvalCaseResults: LD-MRS not connected, aborting!");
00435 return false;
00436 }
00437
00438 result = registerEvent((UINT16)(index_event_aEvalCaseResult));
00439
00440 if (result == true)
00441 {
00442 m_fieldEventIsRegistered = true;
00443 }
00444 else
00445 {
00446 printError("LdmrsSopasLayer::action_subscribeEvalCaseResults: Failed to subscribe, aborting!");
00447 }
00448
00449 return result;
00450 }
00451
00452
00453
00454
00455 bool LdmrsSopasLayer::action_unSubscribeEvalCaseResults()
00456 {
00457
00458 bool result = unregisterEvent((UINT16)(index_event_aEvalCaseResult));
00459
00460 if (result == true)
00461 {
00462 m_fieldEventIsRegistered = false;
00463 }
00464 else
00465 {
00466 printError("LdmrsSopasLayer::action_unSubscribeEvalCases: Failed to un-subscribe, aborting!");
00467 }
00468
00469 return result;
00470 }
00471
00472
00473
00474
00475
00476
00477
00478 bool LdmrsSopasLayer::action_subscribeScanData()
00479 {
00480 bool beVerboseHere = m_beVerbose;
00481
00482 printInfoMessage("LdmrsSopasLayer::action_subscribeScanData: Called.", beVerboseHere);
00483
00484
00485 bool result = false;
00486
00487 if (isConnected() == false)
00488 {
00489 printError("LdmrsSopasLayer::action_subscribeScanData: LD-MRS not connected, aborting!");
00490 return false;
00491 }
00492
00493 result = registerEvent((UINT16)(index_event_ScanDataMonitor));
00494
00495 if (result == true)
00496 {
00497 m_scanEventIsRegistered = true;
00498 }
00499 else
00500 {
00501 printError("LdmrsSopasLayer::action_subscribeScanData: Failed to subscribe, aborting!");
00502 }
00503
00504 printInfoMessage("LdmrsSopasLayer::action_subscribeScanData: Done, leaving.", beVerboseHere);
00505 return result;
00506 }
00507
00508
00509
00510
00511
00512 bool LdmrsSopasLayer::action_unSubscribeScanData()
00513 {
00514
00515 bool result = unregisterEvent((UINT16)(index_event_ScanDataMonitor));
00516
00517 if (result == true)
00518 {
00519 m_scanEventIsRegistered = false;
00520 }
00521 else
00522 {
00523 printError("LdmrsSopasLayer::action_unSubscribeScanData: Failed to un-subscribe, aborting!");
00524 }
00525
00526 return result;
00527 }
00528
00529
00530
00531
00532 bool LdmrsSopasLayer::action_readScanConfig()
00533 {
00534 SopasAnswer* answer = NULL;
00535 bool success = readVariable(index_var_ScanConfig, answer);
00536
00537 if (success && answer != NULL && answer->size() > 0)
00538 {
00539
00540 BYTE* bufferPos = answer->getBuffer();
00541 ScanFreqEnum scanFreqEnum = ScanFreqEnum(memread_UINT8(bufferPos));
00542
00543 switch (scanFreqEnum)
00544 {
00545 case ScanFreq1250:
00546 m_scanFreq = 12.5;
00547 break;
00548 case ScanFreq2500:
00549 m_scanFreq = 25.;
00550 break;
00551 case ScanFreq5000:
00552 m_scanFreq = 50.;
00553 break;
00554 }
00555
00556 UINT16 length = memread_UINT16(bufferPos);
00557
00558 if (length > 0)
00559 {
00560 m_angleResolution = angleToRad(memread_INT16(bufferPos));
00561 m_scanStartAngle = angleToRad(memread_INT16(bufferPos));
00562 m_scanEndAngle = angleToRad(memread_INT16(bufferPos));
00563 }
00564 }
00565
00566 if (answer != NULL)
00567 {
00568 delete answer;
00569 }
00570
00571 return success;
00572 }
00573
00574
00575
00576
00577
00578
00579 bool LdmrsSopasLayer::action_readEvalCases()
00580 {
00581 SopasAnswer* answer = NULL;
00582 bool success = readVariable(index_var_evalCaseParam, answer);
00583
00584 if (success)
00585 {
00586 m_evalCases = colaB_evalCaseDecoder(answer);
00587 }
00588
00589 if (answer != NULL)
00590 {
00591 delete answer;
00592 }
00593
00594 return success;
00595 }
00596
00597
00598
00599
00600 EvalCases LdmrsSopasLayer::colaB_evalCaseDecoder(SopasAnswer* answer)
00601 {
00602 bool beVerboseHere = m_beVerbose;
00603
00604
00605 printInfoMessage("LdmrsSopasLayer::colaB_evalCaseDecoder: Called.", beVerboseHere);
00606
00607 EvalCases evalCases;
00608
00609 if (answer != NULL && answer->size() > 0)
00610 {
00611
00612 BYTE* bufferPos = answer->getBuffer();
00613
00614 UINT16 arrayLength = memread_UINT16(bufferPos);
00615
00616 for (UINT16 i = 0; i < arrayLength; ++i)
00617 {
00618 EvalCase_ptr evalCasePtr(new EvalCase);
00619 EvalCase& evalCase = *evalCasePtr;
00620
00621 evalCase.setVersionNumber(memread_UINT16(bufferPos));
00622 evalCase.setCaseNumber(memread_UINT8(bufferPos));
00623 evalCase.setStrategy(EvalCase::EvaluationStrategy(memread_UINT8(bufferPos)));
00624 evalCase.setResultNegation(memread_UINT8(bufferPos) != 0);
00625 evalCase.setResponseTime(memread_UINT32(bufferPos));
00626 evalCase.setResponseTimeExtended(memread_UINT32(bufferPos));
00627 evalCase.setOutputNumber(memread_UINT8(bufferPos));
00628
00629
00630
00631
00632 UINT8 inputs = memread_UINT8(bufferPos);
00633 evalCase.setLogicalInputState_from_UINT8(inputs);
00634 memread_UINT8(bufferPos);
00635 evalCase.setDistDependent(memread_UINT8(bufferPos) != 0);
00636 evalCase.setMaxRadialCorridor(double(memread_UINT16(bufferPos)) / 1000. );
00637 evalCase.setManipulationPrevention(EvalCase::ManipulationPrevention(memread_UINT8(bufferPos)));
00638 evalCase.setBlankingSize(double(memread_UINT16(bufferPos)) / 1000.);
00639 evalCase.setMinFieldExp(double(memread_UINT16(bufferPos)) / 1000.);
00640 evalCase.setFieldNumber(memread_UINT8(bufferPos));
00641 evalCase.setFilterType(EvalCase::FilterType(memread_UINT8(bufferPos)));
00642
00643 UINT16 nameLength = memread_UINT16(bufferPos);
00644
00645 std::string name = std::string((char *)bufferPos, nameLength);
00646 bufferPos += nameLength;
00647 evalCase.setCaseName(name);
00648 printInfoMessage("LdmrsSopasLayer::colaB_evalCaseDecoder: Decoding EvalCase with the name " +
00649 name + ". Inputs: " + ::toHexString(inputs) + ".", beVerboseHere);
00650
00651 UINT16 commentLength = memread_UINT16(bufferPos);
00652 std::string comment = std::string((char*)bufferPos, commentLength);
00653 bufferPos += commentLength,
00654 evalCase.setComment(comment);
00655
00656 evalCases.add(evalCasePtr);
00657 }
00658 }
00659
00660 printInfoMessage("LdmrsSopasLayer::colaB_evalCaseDecoder: Done. Decoded " +
00661 ::toString(evalCases.getEvalCases().size()) + " cases.", beVerboseHere);
00662
00663 return evalCases;
00664 }
00665
00666
00667
00668
00669
00670 UINT32 LdmrsSopasLayer::colaB_evalCaseEncoder(BYTE* buffer, const EvalCases& evalCases)
00671 {
00672 bool beVerboseHere = m_beVerbose;
00673
00674
00675 printInfoMessage("LdmrsSopasLayer::colaB_evalCaseEncoder: Called.", m_beVerbose);
00676
00677
00678
00679
00680 BYTE* bufferPos = buffer;
00681
00682
00683 UINT16 arrayLength = evalCases.getEvalCases().size();
00684 memwrite_UINT16(bufferPos, arrayLength);
00685
00686
00687 for (UINT16 i = 0; i < arrayLength; i++)
00688 {
00689 EvalCase* evalCase = evalCases.getEvalCases().at(i);
00690
00691 printInfoMessage("LdmrsSopasLayer::colaB_evalCaseEncoder: Encoding EvalCase with the name " +
00692 evalCase->getCaseName() + ".", beVerboseHere);
00693
00694
00695 UINT16 versionNumber = evalCase->getVersionNumber();
00696 memwrite_UINT16(bufferPos, versionNumber);
00697
00698
00699 UINT8 caseNumber = evalCase->getCaseNumber();
00700 memwrite_UINT8(bufferPos, caseNumber);
00701
00702
00703 UINT8 evalStrategy = (UINT8)(evalCase->getStrategy());
00704 memwrite_UINT8(bufferPos, evalStrategy);
00705
00706
00707 bool resultNegation = evalCase->getResultNegation();
00708 if (resultNegation == true)
00709 {
00710 memwrite_UINT8(bufferPos, 1);
00711 }
00712 else
00713 {
00714 memwrite_UINT8(bufferPos, 0);
00715 }
00716
00717
00718 UINT32 responseTime = evalCase->getResponseTime();
00719 memwrite_UINT32(bufferPos, responseTime);
00720
00721
00722 UINT32 responseTimeExtended = evalCase->getResponseTimeExtended();
00723 memwrite_UINT32(bufferPos, responseTimeExtended);
00724
00725
00726 UINT8 outputNumber = evalCase->getOutputNumber();
00727 memwrite_UINT8(bufferPos, outputNumber);
00728
00729
00730 UINT8 logicalInputs = evalCase->getLogicalInputState_as_UINT8();
00731 memwrite_UINT8(bufferPos, logicalInputs);
00732
00733 memread_UINT8(bufferPos);
00734
00735
00736 bool distDependent = evalCase->getDistDependent();
00737 if (distDependent == true)
00738 {
00739 memwrite_UINT8(bufferPos, 1);
00740 }
00741 else
00742 {
00743 memwrite_UINT8(bufferPos, 0);
00744 }
00745
00746
00747 UINT16 maxRadialCorridor = (UINT16)((evalCase->getMaxRadialCorridor() * 1000.0) + 0.5);
00748 memwrite_UINT16(bufferPos, maxRadialCorridor);
00749
00750
00751 UINT8 manipulationPrevention = (UINT8)(evalCase->getManipulationPrevention());
00752 memwrite_UINT8(bufferPos, manipulationPrevention);
00753
00754
00755 UINT16 blankingSize = (UINT16)((evalCase->getBlankingSize() * 1000.0) + 0.5);
00756 memwrite_UINT16(bufferPos, blankingSize);
00757
00758
00759 UINT16 minFieldExp = (UINT16)((evalCase->getMinFieldExp() * 1000.0) + 0.5);
00760 memwrite_UINT16(bufferPos, minFieldExp);
00761
00762
00763 UINT8 fieldNumber = evalCase->getFieldNumber();
00764 memwrite_UINT8(bufferPos, fieldNumber);
00765
00766
00767 UINT8 filterType = (UINT8)(evalCase->getFilterType());
00768 memwrite_UINT8(bufferPos, filterType);
00769
00770
00771 std::string name = evalCase->getCaseName();
00772 memwrite_UINT16(bufferPos, name.length());
00773 memwrite_string(bufferPos, name);
00774
00775
00776 std::string comment = evalCase->getComment();
00777 memwrite_UINT16(bufferPos, comment.length());
00778 memwrite_string(bufferPos, comment);
00779 }
00780
00781
00782 UINT32 len = (UINT32)((UINT64)bufferPos - (UINT64)buffer);
00783
00784 printInfoMessage("LdmrsSopasLayer::colaB_evalCaseEncoder: Done. Encoded " +
00785 ::toString(evalCases.getEvalCases().size()) + " cases. Used " +
00786 ::toString(len) + " bytes.", beVerboseHere);
00787
00788 return len;
00789 }
00790
00791
00792
00793
00794
00795
00796
00797
00798 bool LdmrsSopasLayer::action_writeField(UINT16 fieldNum, const FieldParameter& para)
00799 {
00800 bool beVerboseHere = m_beVerbose;
00801
00802
00803 printInfoMessage("LdmrsSopasLayer::action_writeField: Called for field " + toString(fieldNum) + ".", beVerboseHere);
00804 bool result = false;
00805
00806 if (fieldNum > 15)
00807 {
00808 printError("LdmrsSopasLayer::action_writeField: FieldNum must be 0..15, but is " + toString(fieldNum) + ", aborting!");
00809 return false;
00810 }
00811
00812
00813 UINT32 bufferSize = 1024;
00814 UINT16 usedBufferLen = 0;
00815 BYTE* buffer = new BYTE[bufferSize];
00816 usedBufferLen = colaB_fieldEncoder(buffer, para);
00817
00818
00819 result = writeVariable(index_var_field000 + fieldNum, buffer, usedBufferLen);
00820
00821 if (result == false)
00822 {
00823
00824 printError("LdmrsSopasLayer::action_writeField: Failed to write field " + toString(fieldNum) + ", aborting!");
00825 return false;
00826 }
00827
00828
00829 printInfoMessage("LdmrsSopasLayer::action_writeField: All done, leaving.", beVerboseHere);
00830 return result;
00831 }
00832
00833
00834
00835
00836
00837
00838
00839 bool LdmrsSopasLayer::action_writeEvalCases(const EvalCases& evalCases)
00840 {
00841 bool beVerboseHere = m_beVerbose;
00842
00843
00844 printInfoMessage("LdmrsSopasLayer::action_writeEvalCases: Called, with " + toString(evalCases.getEvalCases().size()) + " eval cases.", beVerboseHere);
00845 bool result = false;
00846
00847 if (evalCases.getEvalCases().size() > 16)
00848 {
00849 printError("LdmrsSopasLayer::action_writeEvalCases: The MRS can only handle up to 16 eval cases, aborting!");
00850 return false;
00851 }
00852
00853
00854 UINT32 bufferSize = 1024;
00855 UINT16 usedBufferLen = 0;
00856 BYTE* buffer = new BYTE[bufferSize];
00857 usedBufferLen = colaB_evalCaseEncoder(buffer, evalCases);
00858
00859
00860 result = writeVariable(index_var_evalCaseParam, buffer, usedBufferLen);
00861
00862 if (result == false)
00863 {
00864
00865 printError("LdmrsSopasLayer::action_writeEvalCases: Failed to write eval cases, aborting!");
00866 return false;
00867 }
00868
00869
00870 printInfoMessage("LdmrsSopasLayer::action_writeEvalCases: All done, leaving.", beVerboseHere);
00871 return result;
00872 }
00873
00874
00875
00876
00877
00878
00879 bool LdmrsSopasLayer::action_readFields()
00880 {
00881 SopasAnswer* answer = NULL;
00882 bool success;
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909 for (UINT16 i = 0; i < MAX_NUM_OF_FIELDS; ++i)
00910 {
00911 printInfoMessage("LdmrsSopasLayer::action_readFields: Reading field " + toString(i) + ".", true);
00912 success = readVariable(index_var_field000 + i, answer);
00913
00914 if ((success == true) &&
00915 (answer != NULL) &&
00916 (answer->size() > 0))
00917 {
00918 FieldParameter* fieldPtr = colaB_fieldDecoder(answer);
00919
00920
00921 if (fieldPtr != NULL)
00922 {
00923 m_fields.add(fieldPtr);
00924 }
00925 }
00926
00927 if (answer != NULL)
00928 {
00929 delete answer;
00930 answer = NULL;
00931 }
00932 }
00933
00934 return success;
00935 }
00936
00938 double LdmrsSopasLayer::angleToRad(INT32 angle)
00939 {
00940 return ((double)angle / 32.0) * deg2rad;
00941 }
00942
00943
00944
00945
00946
00947
00948
00949 FieldParameter* LdmrsSopasLayer::colaB_fieldDecoder(SopasAnswer* answer)
00950 {
00951 bool beVerboseHere = m_beVerbose;
00952
00953
00954
00955 FieldParameter* fieldPtr(new FieldParameter);
00956
00957 if ((answer != NULL) && (answer->size() > 0))
00958 {
00959 FieldParameter& field = *fieldPtr;
00960 BYTE* bufferPos = answer->getBuffer();
00961
00962 field.setDistScaleFactor(memread_float(bufferPos));
00963 field.setDistScaleOffset(memread_float(bufferPos));
00964 field.setAngleScaleFactor(memread_UINT32(bufferPos));
00965 field.setAngleScaleOffset(memread_INT32(bufferPos));
00966 field.setFieldTypeIntern(memread_UINT8(bufferPos));
00967 field.setFieldNumber(memread_UINT8(bufferPos));
00968
00969 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: setDistScaleFactor: " + toString(field.getDistScaleFactor(), 2) + ".", beVerboseHere);
00970 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: setDistScaleOffset: " + toString(field.getDistScaleOffset(), 2) + ".", beVerboseHere);
00971 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: setAngleScaleFactor: " + toString(field.getAngleScaleFactor()) + ".", beVerboseHere);
00972 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: setAngleScaleOffset: " + toString(field.getAngleScaleOffset()) + ".", beVerboseHere);
00973 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: setFieldTypeIntern: " + toString((INT32)(field.getFieldTypeIntern())) + ".", beVerboseHere);
00974 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: Field number: " + toString(field.getFieldNumber()) + ".", beVerboseHere);
00975
00976
00977 UINT16 fieldSeg = memread_UINT16(bufferPos);
00978 if (fieldSeg == 1)
00979 {
00980 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: Found segmented field.", beVerboseHere);
00981
00982 UINT8 arrayLength = memread_UINT16(bufferPos);
00983 FieldSegmented* seg(new FieldSegmented);
00984
00985 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: ArrayLength=" + toString(arrayLength) + ".", beVerboseHere);
00986
00987
00988 for (UINT8 i = 0; i < arrayLength; ++i)
00989 {
00990 UINT16 angleIdx = memread_UINT16(bufferPos);
00991 UINT16 startDist = memread_UINT16(bufferPos);
00992 UINT16 endDist = memread_UINT16(bufferPos);
00993
00994 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: Point " + toString(i) + ": AngIdx=" +
00995 toString(angleIdx) + ", StartDist=" + toString(startDist) + ", EndDist=" +
00996 toString(endDist) + ".", beVerboseHere);
00997
00998
00999 double s = (startDist == 65535) ? ::NaN_double : ((double)startDist / 1000.) * field.getDistScaleFactor() + (field.getDistScaleOffset() / 1000.);
01000 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: StartDist is " + toString(s, 2) + ".", beVerboseHere);
01001
01002
01003 double angle = field.getAngleScaleOffset() + (double)angleIdx * field.getAngleScaleFactor();
01004
01005
01006 angle = -angle;
01007 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: Angle is " + toString(angle, 2) + ".", beVerboseHere);
01008
01009
01010 double e = (endDist == 65535) ? ::NaN_double : ((double)endDist / 1000.) * field.getDistScaleFactor() + (field.getDistScaleOffset() / 1000.);
01011 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: EndDist is " + toString(e, 2) + ".", beVerboseHere);
01012
01013 seg->addPoint(FieldSegmentedPoint(angleToRad(angle), s, e));
01014 }
01015 seg->computePolygon();
01016
01017 field.setField((FieldDescription*)(seg));
01018 }
01019
01020
01021 UINT16 fieldRect = memread_UINT16(bufferPos);
01022 if (fieldRect == 1)
01023 {
01024 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: Found rectangular field.", beVerboseHere);
01025
01026 FieldRectangle* rect(new FieldRectangle);
01027 INT32 refPointAngle = memread_INT32(bufferPos);
01028
01029
01030 refPointAngle = -refPointAngle;
01031 UINT32 refPointDist = (memread_UINT16(bufferPos) * field.getDistScaleFactor()) + field.getDistScaleOffset();
01032 INT32 rotAngle = memread_INT32(bufferPos);
01033
01034
01035 rotAngle = -rotAngle;
01036 UINT32 length = memread_UINT32(bufferPos);
01037 UINT32 width = memread_UINT32(bufferPos);
01038
01039 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: refPointDist is " + toString(refPointDist) + ".", beVerboseHere);
01040 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: refPointAngle is " + toString(-refPointAngle) + ".", beVerboseHere);
01041 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: rotAngle is " + toString(rotAngle, 2) + ".", beVerboseHere);
01042 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: length is " + toString(length, 2) + ".", beVerboseHere);
01043 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: width is " + toString(width, 2) + ".", beVerboseHere);
01044
01045
01046 rect->setRefPointAngle(angleToRad(refPointAngle));
01047 rect->setRefPointDist((double)refPointDist / 1000.);
01048 rect->setRotAngle(angleToRad(rotAngle));
01049 rect->setWidth((double) width / 1000.);
01050 rect->setLength((double) length / 1000.);
01051
01052 rect->computePolygon();
01053
01054 field.setField((FieldDescription*)(rect));
01055 }
01056
01057
01058 UINT16 fieldRad = memread_UINT16(bufferPos);
01059 if (fieldRad == 1)
01060 {
01061 printError("LdmrsSopasLayer::colaB_fieldDecoder: Found radial field, but the LD-MRS does not support radial fields!");
01062 return NULL;
01063 }
01064
01065
01066 UINT16 fieldDyn = memread_UINT16(bufferPos);
01067 if (fieldDyn == 1)
01068 {
01069 printError("LdmrsSopasLayer::colaB_fieldDecoder: Found dynamic field, but the LD-MRS does not support dynamic fields!");
01070 return NULL;
01071 }
01072
01073
01074 UINT16 versionNumber = memread_UINT16(bufferPos);
01075 field.setVersionNumber(versionNumber);
01076 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: Field version number= " + toString(versionNumber) + ".", beVerboseHere);
01077 UINT16 fieldNameLength = memread_UINT16(bufferPos);
01078
01079 if (fieldNameLength > 0)
01080 {
01081 std::string fieldName = colab::getStringFromBuffer(bufferPos, fieldNameLength);
01082 field.setFieldName(fieldName);
01083
01084 printInfoMessage("LdmrsSopasLayer::colaB_fieldDecoder: Field name= " + fieldName + ".", beVerboseHere);
01085 }
01086
01087 UINT16 commentLength = memread_UINT16(bufferPos);
01088
01089 if (commentLength > 0)
01090 {
01091 std::string comment = colab::getStringFromBuffer(bufferPos, commentLength);
01092 field.setComment(comment);
01093 }
01094
01095
01096
01097
01098 }
01099
01100 return fieldPtr;
01101 }
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111 void LdmrsSopasLayer::scanDataDecoder(SopasEventMessage& frame)
01112 {
01113 bool beVerboseHere = m_beVerbose;
01114 beVerboseHere = true;
01115
01116
01117 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Called. Decoding SOPAS frame with length=" +
01118 ::toString(frame.size()) + " bytes.", beVerboseHere);
01119
01120
01121 if (m_weWantScanData == false)
01122 {
01123
01124 return;
01125 }
01126
01127 std::string receivedName;
01128 UINT32 receiveIndex;
01129 BYTE* bufferPos;
01130
01131 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Reading variable index.", beVerboseHere);
01132 receiveIndex = frame.getVariableIndex();
01133
01134 if (receiveIndex != index_event_ScanDataMonitor)
01135 {
01136 printError("LdmrsSopasLayer::scanDataDecoder: This is not a scan data message, aborting!");
01137 return;
01138 }
01139 else
01140 {
01141 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: This is a scan data message.", beVerboseHere);
01142 }
01143
01144
01145 m_scanEventIsRegistered = true;
01146
01147 bufferPos = &(frame.getPayLoad()[5]);
01148 UINT16 versionNumber = memread_UINT16(bufferPos);
01149 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Version number=" + ::toString(versionNumber) + ".", beVerboseHere);
01150
01151
01152 UINT16 logicalNumber = memread_UINT16(bufferPos);
01153 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Logical number of the device=" + ::toString(logicalNumber) + ".", beVerboseHere);
01154 UINT32 serialNumber = memread_UINT32(bufferPos);
01155 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Serial number of the device=" + ::toString(serialNumber) + ".", beVerboseHere);
01156 UINT16 statusBits = memread_UINT16(bufferPos);
01157 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Status bits=" + ::toString(statusBits) + ".", beVerboseHere);
01158
01159
01160 UINT16 telegramCount = memread_UINT16(bufferPos);
01161 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Telegram count=" + ::toString(telegramCount) + ".", beVerboseHere);
01162 UINT16 scanCount = memread_UINT16(bufferPos);
01163 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Scan count=" + ::toString(scanCount) + ".", beVerboseHere);
01164 UINT32 systemTimeScan = memread_UINT32(bufferPos);
01165 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: System time scan=" + ::toString(systemTimeScan) + ".", beVerboseHere);
01166 UINT32 systemTimeTransmit = memread_UINT32(bufferPos);
01167 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: System time transmit=" + ::toString(systemTimeTransmit) + ".", beVerboseHere);
01168 UINT16 inputState = memread_UINT16(bufferPos);
01169 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Input state=" + ::toString(inputState) + ".", beVerboseHere);
01170 UINT16 outputState = memread_UINT16(bufferPos);
01171 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Output state=" + ::toString(outputState) + ".", beVerboseHere);
01172 UINT16 reserved_1 = memread_UINT16(bufferPos);
01173 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Reserved_1=" + ::toString(reserved_1) + ".", beVerboseHere);
01174 UINT32 scanFrequency = memread_UINT32(bufferPos);
01175 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Scan frequency=" + ::doubleToString(double(scanFrequency) / 256.0, 2) + " Hz.", beVerboseHere);
01176 UINT32 measurementFrequency = memread_UINT32(bufferPos);
01177 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Measurement frequency=" + ::doubleToString(double(measurementFrequency) / 10.0, 1) + " kHz.", beVerboseHere);
01178
01179
01180 UINT16 numOfEncoders = memread_UINT16(bufferPos);
01181 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Number of encoder blocks=" + ::toString(numOfEncoders) + ".", beVerboseHere);
01182 for (UINT16 i = 0; i<numOfEncoders; i++)
01183 {
01184 UINT32 encoderPos = memread_UINT32(bufferPos);
01185 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Encoder position=" + ::toString(encoderPos) + " increments.", beVerboseHere);
01186 INT16 encoderSpeed = memread_INT16(bufferPos);
01187 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Encoder speed=" + ::toString(encoderSpeed) + " inc/mm.", beVerboseHere);
01188 }
01189
01190
01191 UINT16 numOf16BitDataChannels = memread_UINT16(bufferPos);
01192 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Number of 16-bit data channels=" + ::toString(numOf16BitDataChannels) + ".", beVerboseHere);
01193
01194
01195
01196 double vAngles[4];
01197 vAngles[0] = -1.6 * 0.75 * deg2rad;
01198 vAngles[1] = -1.6 * 0.25 * deg2rad;
01199 vAngles[2] = 1.6 * 0.25 * deg2rad;
01200 vAngles[3] = 1.6 * 0.75 * deg2rad;
01201
01202
01203 Scan* scan = new Scan;
01204
01205 for (UINT16 i = 0; i<numOf16BitDataChannels; i++)
01206 {
01207
01208 std::string contentType = memread_string(bufferPos, 6);
01209 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Content type=" + contentType + ".", beVerboseHere);
01210 float scaleFactor = memread_float(bufferPos);
01211 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Scale factor=" + ::doubleToString(double(scaleFactor), 10) + ".", beVerboseHere);
01212 float scaleOffset = memread_float(bufferPos);
01213 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Scale offset=" + ::doubleToString(double(scaleOffset), 10) + ".", beVerboseHere);
01214 INT32 startAngle = memread_INT32(bufferPos);
01215 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Start angle=" + ::doubleToString(double(startAngle)/10000.0, 2) + ".", beVerboseHere);
01216 UINT32 angularResolution = memread_UINT16(bufferPos);
01217 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Angular resolution=" + ::doubleToString(double(angularResolution)/10000.0, 2) + ".", beVerboseHere);
01218
01219
01220 UINT16 layer = contentType.c_str()[4] - 'A';
01221 UINT16 echo = contentType.c_str()[5] - '1';
01222 if (layer > 3)
01223 {
01224 printError("LdmrsSopasLayer::scanDataDecoder: We have decoded an invalid layer value of " + toString(layer) + ", allowed is 0..3.");
01225 return;
01226 }
01227 if (echo > 2)
01228 {
01229 printError("LdmrsSopasLayer::scanDataDecoder: We have decoded an invalid echo value of " + toString(echo) + ", allowed is 0..2.");
01230 return;
01231 }
01232
01233
01234 UINT16 numOf16BitData = memread_UINT16(bufferPos);
01235 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Number of 16-bit data=" + ::toString(numOf16BitData) + ".", beVerboseHere);
01236 for (UINT16 d = 0; d<numOf16BitData; d++)
01237 {
01238
01239 UINT16 data = memread_UINT16(bufferPos);
01240
01241
01242
01243 if ((data > 0) && (data != 0xFFFF))
01244 {
01245
01246 ScanPoint& newPoint = scan->addNewPoint();
01247
01248
01249 double hAngle = ((startAngle + d * angularResolution) / 10000.0) * deg2rad;
01250
01251
01252 double dist = (double(data) * scaleFactor) / 1000.0;
01253
01254
01255 newPoint.setPolar (dist, hAngle, vAngles[layer]);
01256
01257
01258 newPoint.setEchoWidth (0.0);
01259 newPoint.setFlags (0);
01260 newPoint.setSourceId (m_deviceId);
01261 newPoint.setLayer (layer);
01262 newPoint.setEchoNum (echo);
01263 }
01264 }
01265 }
01266
01267
01268 UINT16 numOf8BitDataChannels = memread_UINT16(bufferPos);
01269 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Number of 8-bit data channels=" + ::toString(numOf8BitDataChannels) + ".", beVerboseHere);
01270
01271
01272 UINT16 numOfPositionBlocks = memread_UINT16(bufferPos);
01273 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Number of position blocks=" + ::toString(numOfPositionBlocks) + ".", beVerboseHere);
01274 if (numOfPositionBlocks == 1)
01275 {
01276 float posX = memread_float(bufferPos);
01277 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Position X=" + ::doubleToString(double(posX), 2) + ".", beVerboseHere);
01278 float posY = memread_float(bufferPos);
01279 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Position Y=" + ::doubleToString(double(posY), 2) + ".", beVerboseHere);
01280 float posZ = memread_float(bufferPos);
01281 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Position Z=" + ::doubleToString(double(posZ), 2) + ".", beVerboseHere);
01282 float rotX = memread_float(bufferPos);
01283 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Rot angle X=" + ::doubleToString(double(rotX), 2) + ".", beVerboseHere);
01284 float rotY = memread_float(bufferPos);
01285 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Rot angle Y=" + ::doubleToString(double(rotY), 2) + ".", beVerboseHere);
01286 float rotZ = memread_float(bufferPos);
01287 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Rot angle Z=" + ::doubleToString(double(rotZ), 2) + ".", beVerboseHere);
01288 UINT8 rotMode = memread_UINT8(bufferPos);
01289 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Rot mode=" + ::toString(rotMode) + ".", beVerboseHere);
01290 }
01291
01292
01293 UINT16 numOfDeviceNames = memread_UINT16(bufferPos);
01294 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Number of device names=" + ::toString(numOfDeviceNames) + ".", beVerboseHere);
01295 if (numOfDeviceNames == 1)
01296 {
01297 UINT16 deviceNameStringLen = memread_UINT16(bufferPos);
01298 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Device name string length=" + ::toString(deviceNameStringLen) + ".", beVerboseHere);
01299 if (deviceNameStringLen > 16)
01300 {
01301 printError("LdmrsSopasLayer::scanDataDecoder: We have decoded an invalid device name string length of " +
01302 toString(deviceNameStringLen) + ", allowed is 0..16.");
01303 return;
01304 }
01305 std::string deviceName = memread_string(bufferPos, deviceNameStringLen);
01306 }
01307
01308
01309 UINT16 numOfCommentBlocks = memread_UINT16(bufferPos);
01310 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Number of comment blocks=" + ::toString(numOfCommentBlocks) + ".", beVerboseHere);
01311 if (numOfCommentBlocks == 1)
01312 {
01313 UINT16 commentStringLen = memread_UINT16(bufferPos);
01314 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Comment string length=" + ::toString(commentStringLen) + ".", beVerboseHere);
01315 if (commentStringLen > 128)
01316 {
01317 printError("LdmrsSopasLayer::scanDataDecoder: We have decoded an invalid comment string length of " +
01318 toString(commentStringLen) + ", allowed is 0..128.");
01319 return;
01320 }
01321 std::string commentString = memread_string(bufferPos, commentStringLen);
01322 }
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335 ScannerInfo si;
01336 si.setStartAngle(m_scanStartAngle);
01337 si.setEndAngle(m_scanEndAngle);
01338
01339
01340
01341 si.setScanFrequency(double(scanFrequency) / 256.0);
01342 si.setBeamTilt(0.0);
01343 si.setScanFlags(0);
01344 si.setScanNumber(scanCount);
01345 si.setDeviceID(m_deviceId);
01346 si.setScannerType(Sourcetype_LDMRS);
01347 Time start, end;
01348 start.set(double(systemTimeScan) / 1000000.0);
01349 end.set((double(systemTimeScan) / 1000000.0) + (1.0 / (double(scanFrequency) / 256.0)));
01350 si.setTimestamps(start, end);
01351
01352
01353 double yawAngle, pitchAngle, rollAngle, offsetX, offsetY, offsetZ;
01354 yawAngle = 0.0;
01355 pitchAngle = 0.0;
01356 rollAngle = 0.0;
01357 offsetX = 0.0;
01358 offsetY = 0.0;
01359 offsetZ = 0.0;
01360 Position3D mp(yawAngle, pitchAngle, rollAngle, offsetX, offsetY, offsetZ);
01361 si.setMountingPosition(mp);
01362 scan->setScannerInfos(Scan::ScannerInfoVector(1, si));
01363
01364
01365 scan->setSourceId(m_deviceId);
01366 m_manager->setDeviceData(scan);
01367
01368
01369 printInfoMessage("LdmrsSopasLayer::scanDataDecoder: Done, leaving.", beVerboseHere);
01370 }
01371
01372
01373
01374
01375
01376 void LdmrsSopasLayer::evalCaseResultDecoder(SopasEventMessage& frame)
01377 {
01378
01379 printInfoMessage("LdmrsSopasLayer::evalCaseResultDecoder: Called. Decoding SOPAS frame with length=" +
01380 ::toString(frame.size()) + " bytes.", m_beVerbose);
01381
01382 if (m_weWantFieldData == true)
01383 {
01384 std::string receivedName;
01385 UINT32 receiveIndex;
01386 BYTE* bufferPos;
01387
01388 EvalCaseResults* evalCases;
01389 evalCases = new EvalCaseResults();
01390 evalCases->setSourceId(m_deviceId);
01391
01392 printInfoMessage("LdmrsSopasLayer::evalCaseResultDecoder: Reading variable index.", m_beVerbose);
01393 receiveIndex = frame.getVariableIndex();
01394
01395 if (receiveIndex != index_event_aEvalCaseResult)
01396 {
01397 printError("LdmrsSopasLayer::evalCaseResultDecoder: This is not an eval case message, aborting!");
01398 return;
01399 }
01400 else
01401 {
01402 printInfoMessage("LdmrsSopasLayer::evalCaseResultDecoder: This is an eval case message.", m_beVerbose);
01403 }
01404
01405
01406 m_fieldEventIsRegistered = true;
01407
01408
01409 bufferPos = &(frame.getPayLoad()[5]);
01410 UINT16 cases = memread_UINT16 (bufferPos);
01411 printInfoMessage("LdmrsSopasLayer::evalCaseResultDecoder: This frame contains " + ::toString(cases) + " cases to decode.", m_beVerbose);
01412
01413 UINT16 length;
01414 for (UINT16 i = 0; i < cases; i++)
01415 {
01416 EvalCaseResult result;
01417
01418 result.uiVersionNo = memread_UINT16 (bufferPos);
01419 result.CaseHdr.usiNumber = memread_UINT8 (bufferPos);
01420 result.CaseHdr.udiSysCount = memread_UINT32 (bufferPos);
01421 result.CaseHdr.dDistScaleFactor = memread_float (bufferPos);
01422 result.CaseHdr.dDistScaleOffset = memread_float (bufferPos);
01423 result.CaseHdr.uiAngleScaleFactor = memread_UINT32 (bufferPos);
01424 result.CaseHdr.iAngleScaleOffset = memread_INT32 (bufferPos);
01425 UINT8 caseResultMRS = memread_UINT8 (bufferPos);
01426 EvalCaseResult::CaseResult caseResult;
01427 std::string resTxt;
01428 switch (caseResultMRS)
01429 {
01430 case 1:
01431 caseResult = EvalCaseResult::ECR_DONT_CARE;
01432 resTxt = "dont_care";
01433 break;
01434 case 2:
01435
01436 caseResult = EvalCaseResult::ECR_FALLING;
01437 caseResult = EvalCaseResult::ECR_LOW;
01438 resTxt = "low";
01439 break;
01440 case 3:
01441 caseResult = EvalCaseResult::ECR_LOW;
01442 resTxt = "low";
01443 break;
01444 case 4:
01445 caseResult = EvalCaseResult::ECR_DETECTING;
01446 resTxt = "detecting";
01447 break;
01448 case 5:
01449 caseResult = EvalCaseResult::ECR_INVALID;
01450 resTxt = "invalid";
01451 break;
01452 case 6:
01453
01454 caseResult = EvalCaseResult::ECR_RAISING;
01455 caseResult = EvalCaseResult::ECR_HIGH;
01456 resTxt = "high";
01457 break;
01458 case 7:
01459 caseResult = EvalCaseResult::ECR_HIGH;
01460 resTxt = "high";
01461 break;
01462 default:
01463 caseResult = EvalCaseResult::ECR_INVALID;
01464 resTxt = "invalid";
01465 break;
01466 }
01467 result.m_eCaseResult = caseResult;
01468 printInfoMessage("LdmrsSopasLayer::evalCaseResultDecoder: CaseResult is <" + resTxt + ">.", m_beVerbose);
01469
01470
01471
01472 length = memread_UINT16 (bufferPos);
01473
01474
01475
01476
01477
01478
01479
01480 length = memread_UINT16 (bufferPos);
01481 if (length == 0)
01482 {
01483 result.m_sCaseName = "";
01484 }
01485 else
01486 {
01487 result.m_sCaseName = colab::getStringFromBuffer(bufferPos, length);
01488 printInfoMessage("LdmrsSopasLayer::evalCaseResultDecoder: Case name: " + result.m_sCaseName + ".", m_beVerbose);
01489 }
01490
01491 length = memread_UINT16 (bufferPos);
01492 if (length == 0)
01493 {
01494 result.m_sComment = "";
01495 }
01496 else
01497 {
01498 result.m_sComment = colab::getStringFromBuffer(bufferPos, length);
01499 printInfoMessage("LdmrsSopasLayer::evalCaseResultDecoder: Comment: "+ result.m_sComment + ".", m_beVerbose);
01500 }
01501
01502 length = memread_UINT16 (bufferPos);
01503 if (length == 1)
01504 {
01505 result.aTimeBlock.uiYear = memread_UINT16 (bufferPos);
01506 result.aTimeBlock.usiMonth = memread_UINT8 (bufferPos);
01507 result.aTimeBlock.usiDay = memread_UINT8 (bufferPos);
01508 result.aTimeBlock.usiHour = memread_UINT8 (bufferPos);
01509 result.aTimeBlock.usiMinute = memread_UINT8 (bufferPos);
01510 result.aTimeBlock.usiSec = memread_UINT8 (bufferPos);
01511 result.aTimeBlock.udiUSec = memread_UINT32 (bufferPos);
01512 }
01513
01514
01515 evalCases->add(result);
01516 }
01517
01518
01519 if ((evalCases->size() > 0) &&
01520 ((*evalCases) != m_lastEvalCaseResults))
01521 {
01522 m_lastEvalCaseResults = *evalCases;
01523 m_manager->setDeviceData((BasicData*)evalCases);
01524 }
01525 }
01526 else
01527 {
01528 printWarning("LdmrsSopasLayer::evalCaseResultDecoder: Received eval case, but we do not want to listen to eval cases!");
01529
01530 unregisterEvent(index_event_aEvalCaseResult);
01531 }
01532 }
01533
01534
01535
01536
01537 SensorStateInfo LdmrsSopasLayer::getSensorStateInfo()
01538 {
01539 SensorStateInfo sensorStateInfo;
01540 sensorStateInfo.setSourceId(m_deviceId);
01541 sensorStateInfo.setEvalCases(m_evalCases);
01542 sensorStateInfo.setFields(m_fields);
01543
01544 MeasurementList measureList;
01545 measureList.setSourceId(m_deviceId);
01546 Measurement meas;
01547
01548
01549
01550 meas.m_measType = Meastype_DeviceName;
01551 meas.m_textValue = m_scannerName;
01552 measureList.m_list.push_back(meas);
01553
01554 meas.m_measType = Meastype_DeviceVersion;
01555 meas.m_textValue = m_scannerVersion;
01556 measureList.m_list.push_back(meas);
01557
01558 meas.m_measType = Meastype_ScanFreq;
01559 meas.m_doubleValue = m_scanFreq;
01560 measureList.m_list.push_back(meas);
01561
01562 meas.m_measType = Meastype_ScanStartAngle;
01563 meas.m_doubleValue = m_scanStartAngle;
01564 measureList.m_list.push_back(meas);
01565
01566 meas.m_measType = Meastype_ScanStopAngle;
01567 meas.m_doubleValue = m_scanEndAngle;
01568 measureList.m_list.push_back(meas);
01569
01570 meas.m_measType = Meastype_ScanResolution;
01571 meas.m_doubleValue = m_angleResolution;
01572 measureList.m_list.push_back(meas);
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605 sensorStateInfo.setMeasurementList(measureList);
01606 sensorStateInfo.setLastKnownEvalCaseResults(m_lastEvalCaseResults);
01607
01608 return sensorStateInfo;
01609 }
01610
01611
01612
01613
01614
01615
01616
01617 UINT32 LdmrsSopasLayer::colaB_fieldEncoder(BYTE* buffer, const FieldParameter& field)
01618 {
01619 bool beVerboseHere = m_beVerbose;
01620
01621
01622
01623 BYTE* bufferOrg = buffer;
01624
01625
01626 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: DistScaleFactor: " + toString(field.getDistScaleFactor(), 2) + ".", beVerboseHere);
01627 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: DistScaleOffset: " + toString(field.getDistScaleOffset(), 2) + ".", beVerboseHere);
01628 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: AngleScaleFactor: " + toString(field.getAngleScaleFactor()) + ".", beVerboseHere);
01629 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: AngleScaleOffset: " + toString(field.getAngleScaleOffset()) + ".", beVerboseHere);
01630 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: FieldTypeIntern: " + toString((INT32)(field.getFieldTypeIntern())) + ".", beVerboseHere);
01631 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: Field number: " + toString(field.getFieldNumber()) + ".", beVerboseHere);
01632
01633
01634 memwrite_float(buffer, field.getDistScaleFactor());
01635 memwrite_float(buffer, field.getDistScaleOffset());
01636 memwrite_UINT32(buffer, field.getAngleScaleFactor());
01637 memwrite_INT32(buffer, field.getAngleScaleOffset());
01638 memwrite_UINT8(buffer, field.getFieldTypeIntern());
01639 memwrite_UINT8(buffer, field.getFieldNumber());
01640
01641
01642 if (field.getFieldType() == FieldDescription::Segmented)
01643 {
01644
01645 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: Writing a segmented field.", beVerboseHere);
01646
01647 memwrite_UINT16(buffer, 1);
01648
01649
01650 FieldSegmented* seg = (FieldSegmented*)field.getField();
01651 memwrite_UINT16(buffer, seg->getNumberOfPoints());
01652
01653
01654 for (UINT16 p=0; p<seg->getNumberOfPoints(); p++)
01655 {
01656
01657
01658 double angle = seg->getPoints().at(p).getAngle() * rad2deg;
01659 angle = -angle;
01660 angle *= 32;
01661 INT32 angleInt = (INT32)angle;
01662 INT32 angleDiff = angleInt - field.getAngleScaleOffset();
01663 angleDiff /= field.getAngleScaleFactor();
01664 UINT16 angleIdx = (UINT16)angleDiff;
01665 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: AngleIdx = " + toString(angleIdx) + ".", beVerboseHere);
01666
01667 memwrite_UINT16(buffer, angleIdx);
01668
01669
01670 double startDist = seg->getPoints().at(p).getStartDist();
01671 if (startDist == NaN_double)
01672 {
01673
01674 memwrite_UINT16(buffer, 0xFFFF);
01675 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: StartDist = invalid.", beVerboseHere);
01676 }
01677 else
01678 {
01679 startDist *= 1000;
01680 startDist /= field.getDistScaleFactor();
01681 startDist -= field.getDistScaleOffset();
01682 UINT16 startDistInt = (UINT16)startDist;
01683 memwrite_UINT16(buffer, startDistInt);
01684 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: StartDist = " + toString(startDistInt) + ".", beVerboseHere);
01685 }
01686
01687
01688 double endDist = seg->getPoints().at(p).getEndDist();
01689 if (endDist == NaN_double)
01690 {
01691
01692 memwrite_UINT16(buffer, 0xFFFF);
01693 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: EndDist = invalid.", beVerboseHere);
01694 }
01695 else
01696 {
01697 endDist *= 1000;
01698 endDist /= field.getDistScaleFactor();
01699 endDist -= field.getDistScaleOffset();
01700 UINT16 endDistInt = (UINT16)endDist;
01701 memwrite_UINT16(buffer, endDistInt);
01702 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: EndDist = " + toString(endDistInt) + ".", beVerboseHere);
01703 }
01704 }
01705 }
01706 else
01707 {
01708
01709 memwrite_UINT16(buffer, 0);
01710 }
01711
01712
01713 if (field.getFieldType() == FieldDescription::Rectangle)
01714 {
01715 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: Writing rectangular field.", beVerboseHere);
01716 memwrite_UINT16(buffer, 1);
01717
01718 FieldRectangle* rect = (FieldRectangle*)field.getField();
01719
01720
01721 INT32 refPointAngle = rect->getRefPointAngle() * rad2deg * 32.0;
01722 refPointAngle = -refPointAngle;
01723 memwrite_INT32(buffer, refPointAngle);
01724
01725
01726 UINT16 refPointDist = (UINT16)(((rect->getRefPointDist() * 1000.0) / field.getDistScaleFactor()) + field.getDistScaleOffset());
01727 memwrite_UINT16(buffer, refPointDist);
01728
01729
01730 INT32 rotAngle = rect->getRotAngle() * rad2deg * 32.0;
01731 rotAngle = -rotAngle;
01732 memwrite_INT32(buffer, rotAngle);
01733
01734
01735 UINT32 length = rect->getLength() * 1000;
01736 memwrite_UINT32(buffer, length);
01737
01738
01739 UINT32 width = rect->getWidth() * 1000;
01740 memwrite_UINT32(buffer, width);
01741 }
01742 else
01743 {
01744
01745 memwrite_UINT16(buffer, 0);
01746 }
01747
01748
01749 memwrite_UINT16(buffer, 0);
01750
01751
01752 memwrite_UINT16(buffer, 0);
01753
01754
01755 memwrite_UINT16(buffer, (UINT16)field.getVersionNumber());
01756
01757
01758 memwrite_UINT16(buffer, (UINT16)field.getFieldName().length());
01759
01760
01761 if (field.getFieldName().length() > 0)
01762 {
01763 memwrite_string(buffer, field.getFieldName());
01764 }
01765
01766
01767 memwrite_UINT16(buffer, (UINT16)field.getComment().length());
01768
01769
01770 if (field.getComment().length() > 0)
01771 {
01772 memwrite_string(buffer, field.getComment());
01773 }
01774
01775
01776 memwrite_UINT8(buffer, 0x00);
01777
01778
01779 memwrite_UINT16(buffer, 0x000F);
01780
01781
01782 UINT32 len = (UINT32)((UINT64)buffer - (UINT64)bufferOrg);
01783
01784 printInfoMessage("LdmrsSopasLayer::colaB_fieldEncoder: Encoded " + toString(len) + " bytes. All done, leaving.", beVerboseHere);
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795 return len;
01796 }
01797
01798
01799 }