mbicp_driver.cc
Go to the documentation of this file.
1 
177 #include <libplayercore/playercore.h>
178 
179 #include "calcul.h"
180 #include "MbICP.h"
181 
182 #define LASER_MAX_SAMPLES 1024
183 
184 class mbicp : public Driver
185 {
186 
187 public:
188 
189  mbicp( ConfigFile* cf, int section);
190  virtual ~mbicp();
191 
192  virtual int Setup();
193  virtual int Shutdown();
194 
195  virtual int ProcessMessage(QueuePointer &resp_queue,
196  player_msghdr * hdr,
197  void * data);
198 private:
199 
201  float Bw;
202  float Br;
203  float L;
206  float filter;
208  float AsocError;
209  int MaxIter;
210  float errorRatio;
211  float errx_out;
212  float erry_out;
213  float errt_out;
216 
217  player_pose2d_t lastPoseOdom,
218  currentPose,
219  previousPose,
221 
222  player_laser_data_t currentScan,
223  previousScan;
224 
226 
227  //Compute scanMatching
228  void compute();
229 
230  //Transform structures between player and Tdata
231  Tsc playerPose2Tsc(player_pose2d_t posicion);
232  player_pose2d_t Tsc2playerPose(Tsc posicion);
233  void playerLaser2Tpfp(player_laser_data_t laserData,Tpfp *laserDataTpfp);
234 
235  // Main function for device thread.
236  virtual void Main();
237 
238  int SetupDevice();
239  int ShutdownDevice();
240 
241  // Odometry.
242  void ProcessOdom(player_msghdr_t* hdr, player_position2d_data_t &data);
243 
244  // SubtypeLaser
245  void ProcessSubtypeLaser(player_msghdr_t* hdr, player_laser_data_scanpose_t &data);
246 
247  // Check for new commands from server
248  void ProcessCommand(player_msghdr_t* hdr, player_position2d_cmd_pos_t &);
249 
250  // Setup ScanMatching
251  void setupScanMatching();
252 
253  // Position
254  player_devaddr_t posicion_addr;
255 
256  // Odometry and laser
257  Device *odom;
258  player_devaddr_t odom_addr;
259 
260  Device *laser;
261  player_devaddr_t laser_addr;
262 
263 };
264 
266 Driver* mbicp_Init(ConfigFile* cf, int section){
267 
268  return((Driver*)(new mbicp(cf, section)));
269 
270 }
271 
272 
274 void mbicp_Register(DriverTable* table){
275 
276  table->AddDriver("mbicp", mbicp_Init);
277 
278 }
279 
280 
283 
284  havePrevious = false;
285 
286  // Initialise the underlying position device.
287  if(SetupDevice() != 0)
288  return -1;
289 
291 
292  puts("Setup Scanmatching");
293  // Start the driver thread.
294  StartThread();
295  return 0;
296 
297 }
298 
299 
302 
304  this->max_laser_range,
305  this->Bw,
306  this->Br,
307  this->L,
308  this->laserStep,
309  this->MaxDistInter,
310  this->filter,
311  this->ProjectionFilter,
312  this->AsocError,
313  this->MaxIter,
314  this->errorRatio,
315  this->errx_out,
316  this->erry_out,
317  this->errt_out,
318  this->IterSmoothConv);
319 }
320 
321 
324  // Stop the driver thread.
325  StopThread();
326 
327  // Stop the odom device.
328  ShutdownDevice();
329  return 0;
330 }
331 
332 
334 mbicp::mbicp( ConfigFile* cf, int section)
335  : Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN,
336  PLAYER_POSITION2D_CODE){
337 
338 
339  this->max_laser_range = cf->ReadFloat(section, "max_laser_range", 7.9);
340  this->Bw = cf->ReadFloat(section, "angular_window", 1.57/3.0);
341  this->Br = cf->ReadFloat(section, "radial_window", 0.3);
342  this->L = cf->ReadFloat(section, "L", 3.00);
343  this->laserStep = cf->ReadInt(section, "laserStep", 1);
344  this->MaxDistInter = cf->ReadFloat(section, "MaxDistInter", 0.5);
345  this->filter = cf->ReadFloat(section, "filter", 0.85);
346  this->ProjectionFilter = cf->ReadInt(section, "ProjectionFilter", 1);
347  this->AsocError = cf->ReadFloat(section, "AsocError", 0.1);
348  this->MaxIter = cf->ReadInt(section, "MaxIter", 50);
349  this->errorRatio = cf->ReadFloat(section, "errorRatio", 0.0001);
350  this->errx_out = cf->ReadFloat(section, "errx_out", 0.0001);
351  this->erry_out = cf->ReadFloat(section, "erry_out", 0.0001);
352  this->errt_out = cf->ReadFloat(section, "errt_out", 0.0001);
353  this->IterSmoothConv = cf->ReadInt(section, "IterSmoothConv", 2);
354  this->laserPoseTsc.x = cf->ReadFloat(section, "laserPose_x", 0.16);
355  this->laserPoseTsc.y = cf->ReadFloat(section, "laserPose_y", 0);
356  this->laserPoseTsc.tita = cf->ReadFloat(section, "laserPose_th", 0);
357 
358 
359  if(cf->ReadDeviceAddr(&(posicion_addr), section, "provides",
360  PLAYER_POSITION2D_CODE, -1, NULL) != 0){
361  this->SetError(-1);
362  return;
363  }
364 
365  odom = NULL;
366  if(cf->ReadDeviceAddr(&odom_addr, section, "requires",
367  PLAYER_POSITION2D_CODE, -1, NULL) != 0){
368  SetError(-1);
369  return;
370  }
371 
372  laser = NULL;
373  if(cf->ReadDeviceAddr(&laser_addr, section, "requires",
374  PLAYER_LASER_CODE, -1, NULL) != 0){
375  SetError(-1);
376  }
377 
378  return;
379 }
380 
381 
384  return;
385 }
386 
387 
390 
391  if(!(odom = deviceTable->GetDevice(odom_addr))){
392  PLAYER_ERROR("Unable to locate suitable position device");
393  return -1;
394  }
395  if(odom->Subscribe(InQueue) != 0){
396  PLAYER_ERROR("Unable to subscribe to position device");
397  return -1;
398  }
399 
400  if(!(laser = deviceTable->GetDevice(laser_addr))){
401  PLAYER_ERROR("Unable to locate suitable laser device");
402  return -1;
403  }
404  if(laser->Subscribe(InQueue) != 0){
405  PLAYER_ERROR("Unable to subscribe to laser device");
406  return -1;
407  }
408 
409  return 0;
410 }
411 
412 
415  player_position2d_cmd_vel_t cmd;
416 
417  memset(&cmd, 0, sizeof(cmd));
418  // Stop the robot (locks the motors) if the motor state is set to
419  // disabled. The P2OS driver does not respect the motor state.
420  cmd.vel.px = 0;
421  cmd.vel.py = 0;
422  cmd.vel.pa = 0;
423 
424  odom->PutMsg(InQueue, PLAYER_MSGTYPE_CMD, PLAYER_POSITION2D_CMD_VEL,
425  (void*)&cmd,sizeof(cmd),NULL);
426 
427  odom->Unsubscribe(InQueue);
428  laser->Unsubscribe(InQueue);
429  puts("Shutdown mbicp");
430  return 0;
431 }
432 
433 
435 void mbicp::Main(){
436  while (true){
437  // Wait till we get new data
438  Wait();
439 
440  // Test if we are supposed to cancel this thread.
441  pthread_testcancel();
442 
443  // Process any pending requests.
444  ProcessMessages();
445  }
446 }
447 
448 
450 int mbicp::ProcessMessage(QueuePointer &resp_queue,player_msghdr * hdr, void * data){
451 
452  // PLAYER_LASER_DATA_SCANPOSE
453  if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,PLAYER_LASER_DATA_SCANPOSE, laser_addr))
454  {
455  assert(hdr->size == sizeof(player_laser_data_scanpose_t));
456  ProcessSubtypeLaser(hdr, *reinterpret_cast<player_laser_data_scanpose_t *> (data));
457  }else
458 
459  // PLAYER_POSITION2D_DATA_STATE
460  if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,PLAYER_POSITION2D_DATA_STATE, odom_addr))
461  {
462  assert(hdr->size == sizeof(player_position2d_data_t));
463  ProcessOdom(hdr, *reinterpret_cast<player_position2d_data_t *> (data));
464  }else
465 
466  if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,PLAYER_POSITION2D_DATA_GEOM, odom_addr))
467  {
468  assert(hdr->size == sizeof(player_position2d_data_t));
469  player_msghdr_t newhdr = *hdr;
470  newhdr.addr = device_addr;
471  Publish(&newhdr, (void*)&data);
472  }else
473 
474  if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,/*PLAYER_POSITION2D_CMD_VEL*/ -1, device_addr))
475  {
476  assert(hdr->size == sizeof(player_position2d_cmd_vel_t));
477  // make a copy of the header and change the address
478  player_msghdr_t newhdr = *hdr;
479  newhdr.addr = odom_addr;
480  odom->PutMsg(InQueue, &newhdr, (void*)data);
481  }else
482  {
483  if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ, -1, device_addr)){
484  // Pass the request on to the underlying position device and wait for
485  // the reply.
486  Message* msg;
487 
488  if(!(msg = odom->Request(InQueue, hdr->type, hdr->subtype, (void*)data,hdr->size, &hdr->timestamp)))
489  {
490  PLAYER_WARN1("failed to forward config request with subtype: %d\n",hdr->subtype);
491  return(-1);
492  }
493  player_msghdr_t* rephdr = msg->GetHeader();
494  void* repdata = msg->GetPayload();
495  // Copy in our address and forward the response
496  rephdr->addr = device_addr;
497  Publish(resp_queue, rephdr, repdata);
498  delete msg;
499  }
500  }
501  return 0;
502 }
503 
505 void mbicp::ProcessOdom(player_msghdr_t* hdr,player_position2d_data_t &data)
506 {
507 
508 
509  Tsc outComposicion1,
510  outComposicion2,
511  outInversion1;
512 
513  Tsc lastPoseOdomTsc,
514  previousPoseTsc,
515  scanmatchingPoseTsc;
516 
517 
518  lastPoseOdom.px = data.pos.px;
519  lastPoseOdom.py = data.pos.py;
520  lastPoseOdom.pa = data.pos.pa;
521 
522  if (havePrevious)
523  {
524  lastPoseOdomTsc = playerPose2Tsc(lastPoseOdom);
525  previousPoseTsc = playerPose2Tsc(previousPose);
526  scanmatchingPoseTsc = playerPose2Tsc(scanmatchingPose);
527 
528  inversion_sis(&previousPoseTsc, &outInversion1);
529  composicion_sis(&outInversion1, &lastPoseOdomTsc, &outComposicion1);
530  composicion_sis(&scanmatchingPoseTsc, &outComposicion1, &outComposicion2);
531 
532 
533  data.pos.px = outComposicion2.x;
534  data.pos.py = outComposicion2.y;
535  data.pos.pa = outComposicion2.tita;
536 
537 
538  }
539 
540  player_msghdr_t newhdr = *hdr;
541  newhdr.addr = device_addr;
542  Publish(&newhdr, (void*)&data);
543 }
544 
545 
547 void mbicp::ProcessSubtypeLaser(player_msghdr_t* hdr,player_laser_data_scanpose_t &data){
548 
549  lastPoseOdom.px = data.pose.px;
550  lastPoseOdom.py = data.pose.py;
551  lastPoseOdom.pa = data.pose.pa;
552 
554 
555  currentScan.min_angle = data.scan.min_angle;
556  currentScan.max_angle = data.scan.max_angle;
557  currentScan.resolution = data.scan.resolution;
558  currentScan.max_range = data.scan.max_range;
559  currentScan.ranges_count = data.scan.ranges_count;
560  currentScan.intensity_count = data.scan.intensity_count;
561  currentScan.id = data.scan.id;
562 
563  for (unsigned int i=0; i < currentScan.ranges_count; i++){
564  currentScan.ranges[i] = data.scan.ranges[i];
565  currentScan.intensity[i] = data.scan.intensity[i];
566  }
567 
568  if (havePrevious && ( currentPose.px != previousPose.px ||
569  currentPose.py != previousPose.py ||
570  currentPose.pa != previousPose.pa))
571  {
572  compute();
573  }
574 
575  else if (!havePrevious)
576  {
580  havePrevious = true;
581  }
582 }
583 
584 
587 {
588  Tsc previousPoseTsc,
589  currentPoseTsc,
590  scanmatchingPoseTsc,
591  solutionTsc;
592 
593  Tsc outComposicion1,
594  outComposicion2,
595  outComposicion3,
596  outComposicion9,
597  outComposicion10,
598  outComposicion11,
599  outInversion1,
600  outInversion4;
601 
602  Tpfp previousScanTpfp[LASER_MAX_SAMPLES],
603  currentScanTpfp[LASER_MAX_SAMPLES];
604 
605  int salidaMbicp;
606 
607 
608  currentPoseTsc = playerPose2Tsc(currentPose);
609  previousPoseTsc = playerPose2Tsc(previousPose);
610  scanmatchingPoseTsc = playerPose2Tsc(scanmatchingPose);
611 
612 
613  composicion_sis(&previousPoseTsc, &laserPoseTsc, &outComposicion1);
614  composicion_sis(&currentPoseTsc, &laserPoseTsc, &outComposicion2);
615  inversion_sis(&outComposicion1, &outInversion1);
616  composicion_sis(&outInversion1, &outComposicion2, &outComposicion3);
617 
618  playerLaser2Tpfp(previousScan,previousScanTpfp);
619  playerLaser2Tpfp(currentScan,currentScanTpfp);
620 
621  salidaMbicp = MbICPmatcher(previousScanTpfp,currentScanTpfp,&outComposicion3, &solutionTsc);
622 
623  if (salidaMbicp == 1){
624 
625  composicion_sis(&laserPoseTsc,&solutionTsc,&outComposicion9);
626  inversion_sis(&laserPoseTsc, &outInversion4);
627  composicion_sis(&outComposicion9,&outInversion4,&outComposicion10);
628  composicion_sis(&scanmatchingPoseTsc, &outComposicion10, &outComposicion11);
629 
630  scanmatchingPoseTsc.x = outComposicion11.x;
631  scanmatchingPoseTsc.y = outComposicion11.y;
632  scanmatchingPoseTsc.tita = outComposicion11.tita;
633 
634  }
635  else{
636 
637  if (salidaMbicp == 2)
638  fprintf(stderr,"2 : Everything OK but reached the Maximum number of iterations\n");
639  else{
640  if (salidaMbicp == -1)
641  fprintf(stderr,"Failure in the association step\n");
642  if (salidaMbicp == -2)
643  fprintf(stderr,"Failure in the minimization step\n");
644  }
645  composicion_sis(&laserPoseTsc,&outComposicion3,&outComposicion9);
646  inversion_sis(&laserPoseTsc, &outInversion4);
647  composicion_sis(&outComposicion9,&outInversion4,&outComposicion10);
648  composicion_sis(&scanmatchingPoseTsc, &outComposicion10, &outComposicion11);
649 
650  scanmatchingPoseTsc.x = outComposicion11.x;
651  scanmatchingPoseTsc.y = outComposicion11.y;
652  scanmatchingPoseTsc.tita = outComposicion11.tita;
653 
654  }
655 
656  scanmatchingPose = Tsc2playerPose(scanmatchingPoseTsc);
659 }
660 
661 
663 Tsc mbicp::playerPose2Tsc(player_pose2d_t posicion)
664 {
665  Tsc posicionTsc;
666 
667  posicionTsc.x = posicion.px;
668  posicionTsc.y = posicion.py;
669  posicionTsc.tita = posicion.pa;
670  return(posicionTsc);
671 }
672 
673 
675 player_pose2d_t mbicp::Tsc2playerPose(Tsc posicion)
676 {
677  player_pose2d_t posicionPlayer;
678 
679  posicionPlayer.px = posicion.x;
680  posicionPlayer.py = posicion.y;
681  posicionPlayer.pa = posicion.tita;
682  return(posicionPlayer);
683 }
684 
685 
687 void mbicp::playerLaser2Tpfp(player_laser_data_t laserData,Tpfp *laserDataTpfp)
688 {
689  for(unsigned int i=0; i< laserData.ranges_count; i++){
690  laserDataTpfp[i].r = laserData.ranges[i];
691  laserDataTpfp[i].t = laserData.min_angle + (i*laserData.resolution);
692  }
693 }
int ProjectionFilter
player_laser_data_t previousScan
int ShutdownDevice()
int MbICPmatcher(Tpfp *laserK, Tpfp *laserK1, Tsc *sensorMotion, Tsc *solution)
Definition: MbICP.c:162
float Bw
void ProcessCommand(player_msghdr_t *hdr, player_position2d_cmd_pos_t &)
Device * laser
player_pose2d_t Tsc2playerPose(Tsc posicion)
player_pose2d_t currentPose
player_devaddr_t odom_addr
float MaxDistInter
float errorRatio
player_devaddr_t laser_addr
float Br
float t
Definition: TData.h:34
float errx_out
float AsocError
void Init_MbICP_ScanMatching(float max_laser_range, float Bw, float Br, float L, int laserStep, float MaxDistInter, float filter, int ProjectionFilter, float AsocError, int MaxIter, float error_ratio, float error_x, float error_y, float error_t, int IterSmoothConv)
Definition: MbICP.c:122
float L
float tita
Definition: TData.h:45
void ProcessOdom(player_msghdr_t *hdr, player_position2d_data_t &data)
float filter
player_pose2d_t previousPose
player_pose2d_t scanmatchingPose
player_laser_data_t currentScan
int laserStep
#define LASER_MAX_SAMPLES
float r
Definition: TData.h:33
void ProcessSubtypeLaser(player_msghdr_t *hdr, player_laser_data_scanpose_t &data)
player_devaddr_t posicion_addr
#define true
Definition: JSON_checker.c:33
float errt_out
float max_laser_range
void setupScanMatching()
Definition: TData.h:42
float y
Definition: TData.h:44
int SetupDevice()
Device * odom
float erry_out
virtual ~mbicp()
float x
Definition: TData.h:43
int IterSmoothConv
void mbicp_Register(DriverTable *table)
player_pose2d_t lastPoseOdom
bool havePrevious
void playerLaser2Tpfp(player_laser_data_t laserData, Tpfp *laserDataTpfp)
void compute()
void composicion_sis(Tsc *sis1, Tsc *sis2, Tsc *sisOut)
Definition: calcul.c:84
Tsc laserPoseTsc
Tsc playerPose2Tsc(player_pose2d_t posicion)
int MaxIter
Driver * mbicp_Init(ConfigFile *cf, int section)
virtual void Main()
virtual int Shutdown()
virtual int ProcessMessage(QueuePointer &resp_queue, player_msghdr *hdr, void *data)
mbicp(ConfigFile *cf, int section)
Definition: TData.h:32
virtual int Setup()
void inversion_sis(Tsc *sisIn, Tsc *sisOut)
Definition: calcul.c:73


csm
Author(s): Andrea Censi
autogenerated on Tue May 11 2021 02:18:23