source: pacpussensors/trunk/Sick/SickLMSSensor.cpp@ 42

Last change on this file since 42 was 42, checked in by cfougera, 10 years ago

Last version

File size: 25.3 KB
Line 
1/*********************************************************************
2// created: 2014/02/11 - 12:08
3// filename: SickLMSSensor.cpp
4//
5// author: Cyril Fougeray
6// Copyright Heudiasyc UMR UTC/CNRS 6599
7//
8// version: $Id: $
9//
10// purpose: The acquisition class of the SickLMS sensor
11//
12*********************************************************************/
13
14#include "SickLMSSensor.h"
15
16#include "SickSocket.h"
17// #include "Pacpus/kernel/ComponentFactory.h"
18#include "Pacpus/kernel/DbiteException.h"
19#include "Pacpus/kernel/DbiteFileTypes.h"
20#include "Pacpus/kernel/Log.h"
21#include "Pacpus/PacpusTools/ShMem.h"
22
23#include <boost/algorithm/string/split.hpp>
24#include <boost/algorithm/string/classification.hpp>
25
26#include <iostream>
27#include <QTcpSocket>
28#include <string>
29#include <vector>
30
31using namespace std;
32
33// #define SICKLMS_SH_MEM
34
35namespace pacpus {
36
37static const int STX_CHAR = 0x02;
38static const int ETX_CHAR = 0x03;
39
40DECLARE_STATIC_LOGGER("pacpus.base.SickLMSSensor");
41
42// Commands which can be taken into account
43static const std::string SICKLMS_SCANDATA_MESSAGE = "LMDscandata";
44static const std::string SICKLMS_SCANCONFIG_MESSAGE = "LMPscancfg";
45static const int MINIMUM_PARAMETERS_MSG = 6; // ScanConfig message is the smallest relevant message
46
47//////////////////////////////////////////////////////////////////////////
48/// Constructor.
49SickLMSSensor::SickLMSSensor(QObject *parent)
50 : ipaddr_("192.168.0.50"),
51 port_(1211),
52 name_("SickLMSDefault"),
53 recording_(false)
54{
55 LOG_TRACE("constructor ("<<this->name_ << "), default settings");
56
57 S_socket = new SickSocket(this);
58
59 connect(S_socket, SIGNAL(configuration()), this, SLOT(configure()) );
60
61 pendingBytes.time = 0;
62 pendingBytes.previousData = false;
63
64 this->kSickDbtFileName = name_.toStdString()+".dbt";
65 this->kSickUtcFileName = name_.toStdString()+"_data.utc";
66}
67
68SickLMSSensor::SickLMSSensor(QObject *parent, QString name, QString ip, int port, int recording)
69 : ipaddr_(ip),
70 port_(port),
71 name_(name),
72 recording_((bool)recording)
73{
74
75 LOG_TRACE("constructor ("<< this->name_ << "), configuration : " << this->ipaddr_<<":"<<this->port_);
76
77 S_socket = new SickSocket(this);
78
79 connect(S_socket, SIGNAL(configuration()), this, SLOT(configure()) );
80
81 pendingBytes.time = 0;
82 pendingBytes.previousData = false;
83
84 this->kSickDbtFileName = name_.toStdString()+".dbt";
85 this->kSickUtcFileName = name_.toStdString()+"_data.utc";
86}
87
88
89SickLMSSensor::~SickLMSSensor()
90{
91 LOG_TRACE("destructor ("<< this->name_ << ")");
92 delete S_socket;
93}
94
95
96void SickLMSSensor::startActivity()
97{
98
99 LOG_TRACE("Start Activity ("<< this->name_ <<")");
100
101 S_socket->connectToServer(ipaddr_, port_);
102
103 // config can be computed for each measure
104 // askScanCfg();
105
106
107 char buf[100];
108
109// ///LOGIN
110// sprintf(buf, "%c%s%c", 0x02, "sMN SetAccessMode 03 F4724744", 0x03);
111// S_socket->sendToServer(QString(buf));
112
113
114// sprintf(buf, "%c%s%c", 0x02, "sWN LMDscandatacfg 03 00 1 1 0 00 00 0 0 0 0 1 1", 0x03);
115// S_socket->sendToServer(QString(buf));
116
117//// sprintf(buf, "%c%s%c", 0x02, "sWN FREchoFilter 1", 0x03);
118//// S_socket->sendToServer(QString(buf));
119
120/////// SAVE PERMANENT
121// sprintf(buf, "%c%s%c", 0x02, "sMN mEEwriteall", 0x03);
122// S_socket->sendToServer(QString(buf));
123
124//// /// LOGOUT
125// sprintf(buf, "%c%s%c", 0x02, "sMN Run", 0x03);
126// S_socket->sendToServer(QString(buf));
127
128
129 // Start measurement
130 sprintf(buf, "%c%s%c", 0x02, "sEN LMDscandata 1", 0x03);
131 S_socket->sendToServer(QString(buf));
132
133 /// TODO get response from sensor and analyse it to know if measuring has started
134 /// See p23 telegram
135 if(0)
136 LOG_INFO("(Measuring) Data sent permanently");
137
138
139 if (recording_) {
140 LOG_INFO("(Recording) Recording is on.");
141
142 try {
143 dbtFile_.open(kSickDbtFileName, WriteMode, TELEM_SICK_LMS, sizeof(SickLMS_dbt));
144 } catch (DbiteException & e) {
145 cerr << "error opening dbt file: "<< kSickDbtFileName << ", " << e.what() << endl;
146 return;
147 }
148
149 // FIXME: use ofstream
150 // open the file with C function to be sure that it will exist
151 FILE * stream;
152 if (NULL == (stream = fopen(kSickUtcFileName.c_str(), "a+"))) {
153 LOG_FATAL("cannot open file '" << kSickUtcFileName.c_str() << "'");
154 ::exit(-1);
155 } else {
156 fclose(stream);
157 }
158
159 dataFile_.open(kSickUtcFileName.c_str(), ios_base::out|ios_base::binary|ios_base::app);
160 if (!dataFile_) {
161 LOG_FATAL("cannot open file '" << kSickUtcFileName.c_str() << "'");
162 ::exit(-1);
163 }
164 }
165 else
166 LOG_INFO("(Recording) Not recording.");
167
168#ifdef SICKLMS_SH_MEM
169 shmem_ = new ShMem(kSickMemoryName.c_str(), sizeof(ScanSickData));
170#endif
171
172}
173
174
175
176void SickLMSSensor::stopActivity()
177{
178 LOG_TRACE("destructor (" << this->name_ << ")");
179
180 // Stop measurement. Not necessary : when socket is closed, data is no longer sent from sensor
181 char buf[64];
182 sprintf(buf, "%c%s%c", 0x02, "sEN LMDscandata 0", 0x03);
183 S_socket->sendToServer(QString(buf));
184
185 S_socket->closeSocket();
186
187 if (recording_) {
188 LOG_TRACE("(Recording) Recording stopped");
189 dbtFile_.close();
190 dataFile_.close();
191 }
192
193#ifdef SICKLMS_SH_MEM
194 delete shmem_;
195#endif
196 // delete generator;
197
198}
199
200
201void SickLMSSensor::configure(){
202 // Start measuring
203 // S_socket->sendToServer(QString((u_int32_t)0x0020));
204
205 // LOG_TRACE(this->name_ +" configured.");
206}
207
208
209
210
211/* Data must be parsed in slot customEvent */
212void SickLMSSensor::askScanCfg(){
213 char buf[100];
214 sprintf(buf, "%c%s%c", 0x02, "sRN LMPscancfg", 0x03);
215
216 S_socket->sendToServer(QString(buf));
217}
218
219
220
221
222int SickLMSSensor::isMessageComplete(const char* packets, unsigned int size)
223{
224 for(int i = 0; i < size; ++i){
225 if(packets[i] == ETX_CHAR)
226 return i;
227 }
228 return -1;
229}
230
231
232
233int SickLMSSensor::findSTX(const char* packets, const unsigned int size ){
234 int i = 0;
235 while(i < size){
236 if(packets[i] == STX_CHAR)
237 return i;
238 i++;
239 }
240 return -1;
241}
242
243
244void SickLMSSensor::storePendingBytes(road_time_t time)
245{
246 if (!pendingBytes.previousData)
247 {
248 pendingBytes.time = time;
249 pendingBytes.previousData = true;
250 }
251}
252
253
254void SickLMSSensor::reconstituteMessage(const char * packet, const int length, road_time_t time)
255{
256 long indexSTX = 0;
257 long indexETX = 0;
258 long msgSize = 0;
259
260 // we are working on the previous not decoded data + the actual incoming packet
261 pendingBytes.data.append(packet,length);
262 LOG_TRACE("(Packet reconstitution) Pending bytes : " << pendingBytes.data.size() );
263
264
265 while (pendingBytes.data.size() > 0)
266 {
267 // we are looking for the start of frame <STX> (= 0x02)
268 indexSTX = findSTX(pendingBytes.data.c_str() , pendingBytes.data.size() );
269 LOG_TRACE("(Packet reconstitution) Start of text index : " << indexSTX );
270 if (indexSTX == -1)
271 {
272 storePendingBytes(time);
273 // exit the while loop
274 break;
275 }
276
277 // we are verifying if the message is complete
278 indexETX = isMessageComplete(pendingBytes.data.c_str(), pendingBytes.data.size());
279 LOG_TRACE("(Packet reconstitution) End of text index : " << indexETX );
280 if (indexETX == -1)
281 {
282 storePendingBytes(time);
283 // exit the while loop
284 break;
285 }
286
287 // we have a complete message available that we can add to the list
288 MessageLMS msg;
289
290 // we copy the bytes in the body message
291 msgSize = indexETX - indexSTX + 1;
292 char* messageData = (char*)malloc(msgSize+1);
293 memcpy(messageData, pendingBytes.data.c_str() + indexSTX, msgSize);
294
295 msg.body = messageData;
296 msg.msgSize = msgSize;
297
298 // we set the timestamp of the message
299 if (pendingBytes.previousData)
300 {
301 // the timestamp is the one of the previous packet
302 msg.time = pendingBytes.time;
303 pendingBytes.previousData = false;
304 }
305 else
306 {
307 // the timestamp is the one of the actual received packet
308 msg.time = time;
309 }
310
311 // we add the message to the list
312 msgList.push_back(msg);
313 // and we suppress the processed bytes of the pending data
314 pendingBytes.data.erase(0, msgSize);
315 }
316}
317
318
319int SickLMSSensor::splitMessage(MessageLMS* message){
320
321 message->splitMessage = new std::vector<std::string>();
322
323 for(int i; i < message->msgSize; ++i){
324 std::string* str = new std::string();
325 while(message->body[i] != ' ' && i < message->msgSize){
326 str->push_back(message->body[i]);
327 ++i;
328 }
329 message->splitMessage->push_back(*str);
330 delete str;
331 }
332 LOG_TRACE("(splitMessage) Number of parameters into the message : "<< (int)message->splitMessage->size());
333
334 return (int) message->splitMessage->size();
335}
336
337
338
339long SickLMSSensor::xstol(std::string str){
340 long ret = 0;
341 for (std::string::iterator it=str.begin(); it!=str.end(); ++it){
342 if(*it >= 'A' && *it <= 'F'){
343 ret *= 16;
344 ret += (*it - 'A' + 10);
345 }
346 else if (*it >= '0' && *it <= '9'){
347 ret *= 16;
348 ret += (*it - '0');
349 }
350 else
351 LOG_WARN("(conversion) String is not a hex value");
352 }
353 return ret;
354}
355
356
357int SickLMSSensor::processScanData(MessageLMS* msg)
358{
359 // just non-empty arrays will be saved in DBT
360 // so first, we initialize these values to 0 and then fill them if message contains corresponding data
361 msg->data.dist_len1 = 0;
362 msg->data.dist_len2 = 0;
363 msg->data.dist_len3 = 0;
364 msg->data.dist_len4 = 0;
365 msg->data.dist_len5 = 0;
366 msg->data.rssi_len1 = 0;
367 msg->data.rssi_len2 = 0;
368
369
370// for(std::vector<std::string>::iterator it = msg->splitMessage->begin(); it != msg->splitMessage->end(); it++){
371// printf("%s ", (*it).c_str());
372// }
373// printf("\n");
374
375 // 0 //Type of command
376 // 1 //Command
377 // 2 //VersionNumber
378 // 3 //DeviceNumber
379 // 4 //Serial number
380 // 5-6 //DeviceStatus
381 // 00 00 OK
382 // 00 01 Error
383 // 00 02 Pollution Warning
384 // 00 04 Pollution Error
385
386 // 7 //MessageCounter
387
388 LOG_TRACE("(Parsing) Message number 0x"<< msg->splitMessage->at(7).c_str());
389
390 // 8 //ScanCounter
391 // 9 //PowerUpDuration
392 // 10 //TransmissionDuration
393 // 11-12 //InputStatus
394 // 13-14 //OutputStatus
395 // 15 //ReservedByteA
396 // 16 //ScanningFrequency
397 msg->data.scanFrequency = xstol(msg->splitMessage->at(16));
398 LOG_TRACE("(Parsing) Scan frequency "<< msg->data.scanFrequency <<" [1/100 Hz]");
399
400 // 17 //MeasurementFrequency
401
402 // 18 //NumberEncoders
403 int NumberEncoders = xstol(msg->splitMessage->at(18));
404 LOG_TRACE("(Parsing) Number Encoders "<< NumberEncoders);
405
406 for (int i = 0; i < NumberEncoders; i++) {
407 // //EncoderPosition
408 // //EncoderSpeed
409 }
410
411
412 // 18+NumberEncoders*2+1 //NumberChannels16Bit
413 int NumberChannels16Bit = xstol(msg->splitMessage->at(18+NumberEncoders*2+1));
414 LOG_TRACE("(Parsing) Number channels 16Bit : "<<NumberChannels16Bit);
415
416 int totalData16 = 0;
417
418 for (int i = 0; i < NumberChannels16Bit; i++) {
419 int type = -1; // 0 DIST1 1 DIST2 2 (LMS1xx & LMS5xx)
420 // RSSI1 3 RSSI2 (LMS1xx)
421 // 4 DIST3 5 DIST4 6 DIST5 (LMS5xx)
422
423
424 int NumberData;
425
426 std::string content = msg->splitMessage->at(19+NumberEncoders*2+i*6+totalData16+1);
427 // 19+NumberEncoders*2+i*6+totalData16+1 //MeasuredDataContent
428
429 LOG_TRACE("(Parsing 16bit channel #"<<i<<") Measured Data Content : " << content);
430 if (content == "DIST1") {
431 type = 0;
432 } else if (content == "DIST2") {
433 type = 1;
434 } else if (content == "RSSI1") {
435 type = 2;
436 } else if (content == "RSSI2") {
437 type = 3;
438 } else if (content == "DIST3") {
439 type = 4;
440 } else if (content == "DIST4") {
441 type = 5;
442 } else if (content == "DIST5") {
443 type = 6;
444 }
445
446// 19+NumberEncoders*2+i*6+totalData16+2 //ScalingFactor
447 int scalingFactor = 1;
448 if(msg->splitMessage->at(19+NumberEncoders*2+i*6+totalData16+2) == "40000000")
449 scalingFactor = 2;
450 LOG_TRACE("(Parsing 16bit channel #"<<i<<") Scaling factor x"<< scalingFactor);
451
452// 19+NumberEncoders*2+i*6+totalData16+3 //ScalingOffset
453// 19+NumberEncoders*2+i*6+totalData16+4 //Starting angle
454 msg->data.startAngle = xstol(msg->splitMessage->at(19+NumberEncoders*2+i*6+totalData16+4));
455 LOG_TRACE("(Parsing 16bit channel #"<<i<<") Start angle "<< msg->data.startAngle << " [1/10000 degree]");
456
457// 19+NumberEncoders*2+i*6+totalData16+5 //Angular step width
458 msg->data.angleResolution = xstol(msg->splitMessage->at(19+NumberEncoders*2+i*6+totalData16+5));
459 LOG_TRACE("(Parsing 16bit channel #"<<i<<") Angular step width "<< msg->data.angleResolution<<" [1/10000 degree]");
460
461// 19+NumberEncoders*2+i*6+totalData16+6 //NumberData
462 NumberData = xstol(msg->splitMessage->at(19+NumberEncoders*2+i*6+totalData16+6));
463
464 LOG_TRACE("(Parsing 16bit channel #"<<i<<") Number Data for "<<content<<" : "<<NumberData);
465
466 LOG_TRACE("(Parsing 16bit channel #"<<i<<") First data "<<content<<" (index "<<(19+NumberEncoders*2+i*6+totalData16+7)<<") : "<<xstol(msg->splitMessage->at(19+NumberEncoders*2+i*6+totalData16+7)));
467 LOG_TRACE("(Parsing 16bit channel #"<<i<<") Last data "<<content<<" (index "<<(19+NumberEncoders*2+i*6+totalData16+7+NumberData-1)<<") : "<<xstol(msg->splitMessage->at(19+NumberEncoders*2+i*6+totalData16+7+NumberData-1)));
468
469 uint16_t* distPoints = (uint16_t*) malloc(NumberData * sizeof(uint16_t));
470 for (int j = 0; j < NumberData; j++) {
471 distPoints[j] = scalingFactor * xstol(msg->splitMessage->at(19+NumberEncoders*2+i*6+totalData16+7+j));
472 }
473 if (type == 0) {
474 msg->data.dist1 = distPoints;
475 msg->data.dist_len1 = NumberData;
476 } else if (type == 1) {
477 msg->data.dist2 = distPoints;
478 msg->data.dist_len2 = NumberData;
479 } else if (type == 2) {
480 msg->data.rssi1 = distPoints;
481 msg->data.rssi_len1 = NumberData;
482 } else if (type == 3) {
483 msg->data.rssi2 = distPoints;
484 msg->data.rssi_len2 = NumberData;
485 } else if (type == 4) {
486 msg->data.dist3 = distPoints;
487 msg->data.dist_len3 = NumberData;
488 } else if (type == 5) {
489 msg->data.dist4 = distPoints;
490 msg->data.dist_len4 = NumberData;
491 } else if (type == 6) {
492 msg->data.dist5 = distPoints;
493 msg->data.dist_len5 = NumberData;
494 }
495 totalData16 += NumberData;
496
497 }
498
499
500// 19+NumberEncoders*2+NumberChannels16Bit*6+totalData16+1 //NumberChannels8Bit
501 int NumberChannels8Bit = xstol(msg->splitMessage->at(19+NumberEncoders*2+NumberChannels16Bit*6+totalData16+1));
502 LOG_TRACE("(Processing) Number channels 8Bit : "<<NumberChannels8Bit);
503
504 LOG_INFO("(Parsing) 8bit channel not implemented yet !");
505
506/*
507// int totalData8 = 0;
508// for (int i = 0; i < NumberChannels8Bit; i++) {
509
510// int type = -1;
511
512// std::string content = msg->splitMessage->at(21+NumberEncoders*2+NumberChannels16Bit*6+totalData16+totalData8+i*6);
513// LOG_TRACE("(Parsing 8bit channel) Measured Data Content : " << content);
514// if (content == "DIST1") {
515// type = 0;
516// } else if (content=="DIST2") {
517// type = 1;
518// } else if (content=="RSSI1") {
519// type = 2;
520// } else if (content == "RSSI2") {
521// type = 3;
522// }
523
524// 21+NumberEncoders*2+NumberChannels16Bit*6+totalData16+i*6+1 //ScalingFactor
525// 21+NumberEncoders*2+NumberChannels16Bit*6+totalData16+i*6+2 //ScalingOffset
526// 21+NumberEncoders*2+NumberChannels16Bit*6+totalData16+i*6+3 //Starting angle
527// 21+NumberEncoders*2+NumberChannels16Bit*6+totalData16+i*6+4 //Angular step width
528// 21+NumberEncoders*2+NumberChannels16Bit*6+totalData16+i*6+5 //NumberData
529
530// int NumberData = xstol(msg->splitMessage->at(21+NumberEncoders*2+NumberChannels16Bit*6+totalData16+totalData8+i*6+5));
531// LOG_TRACE("(Parsing 16bit channel) Number Data for "<<content<<" : "<<NumberData);
532
533// sscanf(tok, "%X", &NumberData);
534
535// LOG_TRACE("(Processing) Number data : "<< NumberData);
536
537// if (type == 0) {
538// msg->data.dist_len1 = NumberData;
539// } else if (type == 1) {
540// msg->data.dist_len2 = NumberData;
541// } else if (type == 2) {
542// msg->data.rssi_len1 = NumberData;
543// } else if (type == 3) {
544// msg->data.rssi_len2 = NumberData;
545// }
546// for (int i = 0; i < NumberData; i++) {
547// int dat;
548// tok = strtok(NULL, " "); //data
549// sscanf(tok, "%X", &dat);
550
551// if (type == 0) {
552// msg->data.dist1[i] = dat;
553// } else if (type == 1) {
554// msg->data.dist2[i] = dat;
555// } else if (type == 2) {
556// msg->data.rssi1[i] = dat;
557// } else if (type == 3) {
558// msg->data.rssi2[i] = dat;
559// }
560// }
561 } // 8bit channel
562*/
563
564}
565
566
567void SickLMSSensor::writeData(MessageLMS &msg)
568{
569 SickLMS_dbt entry;
570 entry.angleResolution = msg.data.angleResolution;
571 entry.scanNumber = xstol(msg.splitMessage->at(7));
572 entry.scannerStatus = xstol(msg.splitMessage->at(6));
573 /* time in SickLMS_dbt is used uniquely when DBT file read */
574 // entry.time = msg.time;
575 // entry.timerange = msg.timerange;
576 entry.scanFrequency = msg.data.scanFrequency;
577 entry.angleResolution = msg.data.angleResolution;
578 entry.startAngle = msg.data.startAngle;
579
580 // Initialisation
581 entry.dist_len1 = entry.dataPos_dist1 = 0;
582 entry.dist_len2 = entry.dataPos_dist2 = 0;
583 entry.dist_len3 = entry.dataPos_dist3 = 0;
584 entry.dist_len4 = entry.dataPos_dist4 = 0;
585 entry.dist_len5 = entry.dataPos_dist5 = 0;
586 entry.rssi_len1 = entry.dataPos_rssi1 = 0;
587 entry.rssi_len2 = entry.dataPos_rssi2 = 0;
588
589 if(msg.data.dist_len1){
590 entry.dist_len1 = msg.data.dist_len1;
591 entry.dataPos_dist1 = dataFile_.tellp();
592
593 for (unsigned int i = 0 ; i < msg.data.dist_len1; ++i) {
594 dataFile_.write(reinterpret_cast<char*>(&(msg.data.dist1[i])), sizeof(u_int16_t));
595 }
596
597 free(msg.data.dist1);
598 }
599 if(msg.data.dist_len2){
600 entry.dist_len2 = msg.data.dist_len2;
601 entry.dataPos_dist2 = dataFile_.tellp();
602
603 for (unsigned int i = 0 ; i < msg.data.dist_len2; ++i) {
604 dataFile_.write(reinterpret_cast<char*>(&(msg.data.dist2[i])), sizeof(u_int16_t));
605 }
606
607 free(msg.data.dist2);
608 }
609 if(msg.data.dist_len3){
610 entry.dist_len3 = msg.data.dist_len3;
611 entry.dataPos_dist3 = dataFile_.tellp();
612
613 for (unsigned int i = 0 ; i < msg.data.dist_len3; ++i) {
614 dataFile_.write(reinterpret_cast<char*>(&(msg.data.dist3[i])), sizeof(u_int16_t));
615 }
616
617 free(msg.data.dist3);
618 }
619 if(msg.data.dist_len4){
620 entry.dist_len4 = msg.data.dist_len4;
621 entry.dataPos_dist4 = dataFile_.tellp();
622
623 for (unsigned int i = 0 ; i < msg.data.dist_len4; ++i) {
624 dataFile_.write(reinterpret_cast<char*>(&(msg.data.dist4[i])), sizeof(u_int16_t));
625 }
626
627 free(msg.data.dist4);
628 }
629 if(msg.data.dist_len5){
630 entry.dist_len5 = msg.data.dist_len5;
631 entry.dataPos_dist5 = dataFile_.tellp();
632
633 for (unsigned int i = 0 ; i < msg.data.dist_len5; ++i) {
634 dataFile_.write(reinterpret_cast<char*>(&(msg.data.dist5[i])), sizeof(u_int16_t));
635 }
636
637 free(msg.data.dist5);
638 }
639 if(msg.data.rssi_len1){
640 entry.rssi_len1 = msg.data.rssi_len1;
641 entry.dataPos_rssi1 = dataFile_.tellp();
642
643 for (unsigned int i = 0 ; i < msg.data.rssi_len1; ++i) {
644 dataFile_.write(reinterpret_cast<char*>(&(msg.data.rssi1[i])), sizeof(u_int16_t));
645 }
646
647 free(msg.data.rssi1);
648 }
649 if(msg.data.rssi_len2){
650 entry.rssi_len2 = msg.data.rssi_len2;
651 entry.dataPos_rssi2 = dataFile_.tellp();
652
653 for (unsigned int i = 0 ; i < msg.data.rssi_len2; ++i) {
654 dataFile_.write(reinterpret_cast<char*>(&(msg.data.rssi2[i])), sizeof(u_int16_t));
655 }
656
657 free(msg.data.rssi2);
658 }
659 // add a magic word to delimit the block of data
660 int32_t utcMagicWord = UTC_MAGIC_WORD;
661 dataFile_.write(reinterpret_cast<char*>(&(utcMagicWord)), sizeof(int32_t));
662
663 // write DBT
664 try {
665 dbtFile_.writeRecord(msg.time, msg.timerange, (char *) &entry, sizeof(SickLMS_dbt));
666 } catch (DbiteException & e) {
667 cerr << "error writing data: " << e.what() << endl;
668 return;
669 }
670
671}
672
673
674
675
676void SickLMSSensor::customEvent(QEvent * e)
677{
678 char answerMsg1[10];
679 sprintf(answerMsg1, "%c%s", 0x02, "sRA");
680 char answerMsg2[10];
681 sprintf(answerMsg2, "%c%s", 0x02, "sSN");
682
683 SickFrame * frame = ((SickFrameEvent*)e)->frame;
684
685 // we try to find some messages in the current packet + the pending bytes of the previous incoming data
686 reconstituteMessage(frame->msg, frame->size, frame->time);
687
688 // we delete the heap variable
689 delete frame;
690
691 // we test if we have some messages to decode
692 while ( !msgList.empty() )
693 {
694 // get the first (the eldest) message and process it
695 MessageLMS* msgToProcess = &(msgList.front());
696
697 // verify if the message is worth to be decoded
698 if(!strncmp(answerMsg1, msgToProcess->body, 4) || !strncmp(answerMsg2, msgToProcess->body, 4)){
699
700 if(splitMessage(msgToProcess) >= MINIMUM_PARAMETERS_MSG){
701
702 std::string type = msgToProcess->splitMessage->at(1);
703
704 LOG_TRACE("(Message type) "<< type);
705
706 if (type == SICKLMS_SCANDATA_MESSAGE)
707 {
708 LOG_TRACE("Scan data message !");
709
710 processScanData(msgToProcess);
711
712 // write data on the disk (dbt + utc)
713 if (recording_)
714 writeData(msgList.front());
715
716
717 #ifdef SICKLMS_SH_MEM
718 /// push data in shared memory
719 // First the scan info
720 SickLMS_shMem toWrite;
721 toWrite.time = msgToProcess.time;
722 toWrite.timerange = msgToProcess.timerange;
723 toWrite.scanInfo = msgToProcess.hScan;
724 shmem_->write(toWrite, sizeof(SickLMS_shMem));
725
726 // Then, the points
727 for (unsigned int i = 0 ; i < msgToProcess.hScan.numPoints ; ++i) {
728 shmem_->write((msg.body + i*sizeof(ScanPoint)), sizeof(ScanPoint));
729 }
730 #endif
731 }
732 else if (type == SICKLMS_SCANCONFIG_MESSAGE){
733 LOG_TRACE("Scan configuration message !");
734
735 // get the values as (unsigned or signed) integer
736 mainCfg.scaningFrequency = xstol(msgToProcess->splitMessage->at(2));
737 mainCfg.angleResolution = xstol(msgToProcess->splitMessage->at(4));
738 mainCfg.startAngle = xstol(msgToProcess->splitMessage->at(5));
739 mainCfg.stopAngle = xstol(msgToProcess->splitMessage->at(6));
740 LOG_TRACE("(Scan config) Frequency : "<<mainCfg.scaningFrequency<<", Resolution : "<<mainCfg.angleResolution);
741 LOG_TRACE("(Scan config) Start angle : "<<mainCfg.startAngle<<", Stop angle : "<<mainCfg.stopAngle);
742 }
743 }
744
745 delete msgToProcess->splitMessage;
746 }
747
748
749 // (malloced memory) raw data no longer needed
750 free(msgToProcess->body);
751
752
753 // removes the processed item of the list
754 msgList.pop_front();
755 }
756}
757
758} // namespace pacpus
Note: See TracBrowser for help on using the repository browser.