00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <stdio.h>
00030 #include <limits.h>
00031 #include <math.h>
00032 #include <sys/types.h>
00033 #include <stdlib.h>
00034 #include <unistd.h>
00035
00036 #include <libplayercore/error.h>
00037
00038 #include "sip.h"
00039
00040
00041 static player_actarray_actuator_t liftActuator;
00042
00043 static player_blobfinder_blob_t cmucamBlob;
00044
00045 void SIP::FillStandard(player_p2os_data_t* data)
00046 {
00048
00049
00050
00051 data->position.pos.px = this->x_offset / 1e3;
00052 data->position.pos.py = this->y_offset / 1e3;
00053
00054
00055 if(this->angle_offset != 0)
00056 {
00057 double rot = DTOR(this->angle_offset);
00058 data->position.pos.px += ((this->xpos/1e3) * cos(rot) -
00059 (this->ypos/1e3) * sin(rot));
00060 data->position.pos.py += ((this->xpos/1e3) * sin(rot) +
00061 (this->ypos/1e3) * cos(rot));
00062 data->position.pos.pa = DTOR(this->angle_offset + angle);
00063 }
00064 else
00065 {
00066 data->position.pos.px += this->xpos / 1e3;
00067 data->position.pos.py += this->ypos / 1e3;
00068 data->position.pos.pa = DTOR(this->angle);
00069 }
00070 data->position.vel.px = (((this->lvel) + (this->rvel) ) / 2) / 1e3;
00071 data->position.vel.py = 0.0;
00072 data->position.vel.pa = ((double)(this->rvel - this->lvel) /
00073 (2.0/PlayerRobotParams[param_idx].DiffConvFactor));
00074 data->position.stall = (unsigned char)(this->lwstall || this->rwstall);
00075
00077
00078 memset(&(data->compass),0,sizeof(data->compass));
00079 data->compass.pos.pa = DTOR(this->compass);
00080
00082
00083 data->sonar.ranges_count = PlayerRobotParams[param_idx].SonarNum;
00084 data->sonar.ranges = new float[data->sonar.ranges_count];
00085 for(int i=0;i<MIN(PlayerRobotParams[param_idx].SonarNum,sonarreadings);i++)
00086 data->sonar.ranges[i] = this->sonars[i] / 1e3;
00087
00089
00090 unsigned char gripState = timer >> 8;
00091 if ((gripState & 0x01) && (gripState & 0x02) && !(gripState & 0x04))
00092 data->gripper.state = PLAYER_GRIPPER_STATE_ERROR;
00093 else
00094 data->gripper.state = (gripState & 0x01) ? PLAYER_GRIPPER_STATE_OPEN :
00095 ((gripState & 0x02) ? PLAYER_GRIPPER_STATE_CLOSED :
00096 ((gripState & 0x04) ? PLAYER_GRIPPER_STATE_MOVING : PLAYER_GRIPPER_STATE_ERROR));
00097 data->gripper.beams = (digin & 0x02) & (digin & 0x04);
00098 data->gripper.stored = 0;
00099
00101
00102 data->lift.actuators_count = 1;
00103 data->lift.actuators = &liftActuator;
00104 data->lift.actuators[0].speed = 0;
00105 data->lift.actuators[0].acceleration = -1;
00106 data->lift.actuators[0].current = -1;
00107 if ((gripState & 0x10) && (gripState & 0x20) && !(gripState & 0x40))
00108 {
00109
00110
00111 data->lift.actuators[0].state = PLAYER_ACTARRAY_ACTSTATE_IDLE;
00112 data->lift.actuators[0].position = lastLiftPos;
00113 }
00114 else if (gripState & 0x10)
00115 {
00116 data->lift.actuators[0].state = PLAYER_ACTARRAY_ACTSTATE_IDLE;
00117 data->lift.actuators[0].position = 1.0f;
00118 }
00119 else if (gripState & 0x20)
00120 {
00121 data->lift.actuators[0].state = PLAYER_ACTARRAY_ACTSTATE_IDLE;
00122 data->lift.actuators[0].position = 0.0f;
00123 }
00124 else if (gripState & 0x40)
00125 {
00126 data->lift.actuators[0].state = PLAYER_ACTARRAY_ACTSTATE_MOVING;
00127
00128 data->lift.actuators[0].position = lastLiftPos;
00129 }
00130 else
00131 {
00132 data->lift.actuators[0].state = PLAYER_ACTARRAY_ACTSTATE_STALLED;
00133 }
00134
00136
00137 unsigned int bump_count = PlayerRobotParams[param_idx].NumFrontBumpers + PlayerRobotParams[param_idx].NumRearBumpers;
00138 if (data->bumper.bumpers_count != bump_count)
00139 {
00140 data->bumper.bumpers_count = bump_count;
00141 delete [] data->bumper.bumpers;
00142 data->bumper.bumpers = new uint8_t[bump_count];
00143 }
00144 int j = 0;
00145 for(int i=PlayerRobotParams[param_idx].NumFrontBumpers-1;i>=0;i--)
00146 data->bumper.bumpers[j++] =
00147 (unsigned char)((this->frontbumpers >> i) & 0x01);
00148 for(int i=PlayerRobotParams[param_idx].NumRearBumpers-1;i>=0;i--)
00149 data->bumper.bumpers[j++] =
00150 (unsigned char)((this->rearbumpers >> i) & 0x01);
00151
00153
00154
00155 data->power.valid = PLAYER_POWER_MASK_VOLTS | PLAYER_POWER_MASK_PERCENT;
00156 data->power.volts = this->battery / 1e1;
00157 data->power.percent = 1e2 * (data->power.volts / P2OS_NOMINAL_VOLTAGE);
00158
00160
00161 data->dio.count = (unsigned char)8;
00162 data->dio.bits = (unsigned int)this->digin;
00163
00165
00166
00167 data->aio.voltages_count = (unsigned char)1;
00168 if (!data->aio.voltages)
00169 data->aio.voltages = new float[1];
00170 data->aio.voltages[0] = (this->analog / 255.0) * 5.0;
00171 }
00172
00173 void SIP::FillGyro(player_p2os_data_t* data)
00174 {
00176
00177 memset(&(data->gyro),0,sizeof(data->gyro));
00178 data->gyro.pos.pa = DTOR(this->gyro_rate);
00179 }
00180
00181 void SIP::FillSERAUX(player_p2os_data_t* data)
00182 {
00183
00184
00185
00186
00187
00188
00189
00190 data->blobfinder.blobs = &cmucamBlob;
00191 memset(data->blobfinder.blobs,0,
00192 sizeof(player_blobfinder_blob_t));
00193 data->blobfinder.width = CMUCAM_IMAGE_WIDTH;
00194 data->blobfinder.height = CMUCAM_IMAGE_HEIGHT;
00195
00196 if (blobarea > 1)
00197 {
00198 data->blobfinder.blobs_count = 1;
00199 if (!data->blobfinder.blobs)
00200 data->blobfinder.blobs = new player_blobfinder_blob_t[1];
00201 data->blobfinder.blobs[0].color = this->blobcolor;
00202 data->blobfinder.blobs[0].x = this->blobmx;
00203 data->blobfinder.blobs[0].y = this->blobmy;
00204 data->blobfinder.blobs[0].left = this->blobx1;
00205 data->blobfinder.blobs[0].right = this->blobx2;
00206 data->blobfinder.blobs[0].top = this->bloby1;
00207 data->blobfinder.blobs[0].bottom = this->bloby2;
00208 data->blobfinder.blobs[0].area = this->blobarea;
00209 data->blobfinder.blobs[0].range = this->blobconf;
00210 }
00211 else
00212 data->blobfinder.blobs_count = 0;
00213 }
00214
00215 void SIP::FillArm(player_p2os_data_t* data)
00216 {
00218
00219 data->actArray.actuators_count = armNumJoints;
00220 data->actArray.actuators = new player_actarray_actuator_t[armNumJoints];
00221 memset (data->actArray.actuators, 0, sizeof (player_actarray_actuator_t) * armNumJoints);
00222 for (int ii = 0; ii < armNumJoints; ii++)
00223 {
00224 data->actArray.actuators[ii].position = armJointPosRads[ii];
00225 data->actArray.actuators[ii].speed = 0;
00226 data->actArray.actuators[ii].acceleration = -1;
00227 data->actArray.actuators[ii].current = -1;
00228
00229
00230
00231
00232 if (armJointMoving[ii])
00233 data->actArray.actuators[ii].state = PLAYER_ACTARRAY_ACTSTATE_MOVING;
00234 else if (armJointPos[ii] == armJointTargetPos[ii])
00235 data->actArray.actuators[ii].state = PLAYER_ACTARRAY_ACTSTATE_IDLE;
00236 else
00237 data->actArray.actuators[ii].state = PLAYER_ACTARRAY_ACTSTATE_STALLED;
00238 }
00239
00241
00242 memset (&(data->armGripper), 0, sizeof (player_gripper_data_t));
00243 if (armJointMoving[5])
00244 data->armGripper.state = PLAYER_GRIPPER_STATE_MOVING;
00245 else if (armJointPos[5] == armJointTargetPos[5])
00246 if (armJointPos[5] > 128)
00247 data->armGripper.state = PLAYER_GRIPPER_STATE_OPEN;
00248 else
00249 data->armGripper.state = PLAYER_GRIPPER_STATE_CLOSED;
00250 else
00251 data->armGripper.state = PLAYER_GRIPPER_STATE_ERROR;
00252 data->armGripper.beams = 0;
00253 data->armGripper.stored = 0;
00254 }
00255
00256 int SIP::PositionChange( unsigned short from, unsigned short to )
00257 {
00258 int diff1, diff2;
00259
00260
00261 if ( to > from ) {
00262 diff1 = to - from;
00263 diff2 = - ( from + 4096 - to );
00264 }
00265 else {
00266 diff1 = to - from;
00267 diff2 = 4096 - from + to;
00268 }
00269
00270 if ( abs(diff1) < abs(diff2) )
00271 return(diff1);
00272 else
00273 return(diff2);
00274
00275 }
00276
00277 void SIP::Print()
00278 {
00279 int i;
00280
00281 printf("lwstall:%d rwstall:%d\n", lwstall, rwstall);
00282
00283 printf("Front bumpers: ");
00284 for(int i=0;i<5;i++) {
00285 printf("%d", (frontbumpers >> i) & 0x01 );
00286 }
00287 puts("");
00288
00289 printf("Rear bumpers: ");
00290 for(int i=0;i<5;i++) {
00291 printf("%d", (rearbumpers >> i) & 0x01 );
00292 }
00293 puts("");
00294
00295 printf("status: 0x%x analog: %d ", status, analog);
00296 printf("digin: ");
00297 for(i=0;i<8;i++) {
00298 printf("%d", (digin >> 7-i ) & 0x01);
00299 }
00300 printf(" digout: ");
00301 for(i=0;i<8;i++) {
00302 printf("%d", (digout >> 7-i ) & 0x01);
00303 }
00304 puts("");
00305 printf("battery: %d compass: %d sonarreadings: %d\n", battery, compass, sonarreadings);
00306 printf("xpos: %d ypos:%d ptu:%hu timer:%hu\n", xpos, ypos, ptu, timer);
00307 printf("angle: %d lvel: %d rvel: %d control: %d\n", angle, lvel, rvel, control);
00308
00309 PrintSonars();
00310 PrintArmInfo ();
00311 PrintArm ();
00312 }
00313
00314 void SIP::PrintSonars()
00315 {
00316 printf("Sonars: ");
00317 for(int i = 0; i < 16; i++){
00318 printf("%hu ", sonars[i]);
00319 }
00320 puts("");
00321 }
00322
00323 void SIP::PrintArm ()
00324 {
00325 printf ("Arm power is %s\tArm is %sconnected\n", (armPowerOn ? "on" : "off"), (armConnected ? "" : "not "));
00326 printf ("Arm joint status:\n");
00327 for (int ii = 0; ii < 6; ii++)
00328 printf ("Joint %d %s %d\n", ii + 1, (armJointMoving[ii] ? "Moving " : "Stopped"), armJointPos[ii]);
00329 }
00330
00331 void SIP::PrintArmInfo ()
00332 {
00333 printf ("Arm version:\t%s\n", armVersionString);
00334 printf ("Arm has %d joints:\n", armNumJoints);
00335 printf (" |\tSpeed\tHome\tMin\tCentre\tMax\tTicks/90\n");
00336 for (int ii = 0; ii < armNumJoints; ii++)
00337 printf ("%d |\t%d\t%d\t%d\t%d\t%d\t%d\n", ii, armJoints[ii].speed, armJoints[ii].home, armJoints[ii].min, armJoints[ii].centre, armJoints[ii].max, armJoints[ii].ticksPer90);
00338 }
00339
00340 void SIP::ParseStandard( unsigned char *buffer )
00341 {
00342 int cnt = 0, change;
00343 unsigned short newxpos, newypos;
00344
00345 status = buffer[cnt];
00346 cnt += sizeof(unsigned char);
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 newxpos = ((buffer[cnt] | (buffer[cnt+1] << 8))
00359 & 0xEFFF) % 4096;
00360
00361 if (xpos!=INT_MAX) {
00362 change = (int) rint(PositionChange( rawxpos, newxpos ) *
00363 PlayerRobotParams[param_idx].DistConvFactor);
00364 if (abs(change)>100)
00365 PLAYER_WARN1("invalid odometry change [%d]; odometry values are tainted", change);
00366 else
00367 xpos += change;
00368 }
00369 else
00370 xpos = 0;
00371 rawxpos = newxpos;
00372 cnt += sizeof(short);
00373
00374 newypos = ((buffer[cnt] | (buffer[cnt+1] << 8))
00375 & 0xEFFF) % 4096;
00376
00377 if (ypos!=INT_MAX) {
00378 change = (int) rint(PositionChange( rawypos, newypos ) *
00379 PlayerRobotParams[param_idx].DistConvFactor);
00380 if (abs(change)>100)
00381 PLAYER_WARN1("invalid odometry change [%d]; odometry values are tainted", change);
00382 else
00383 ypos += change;
00384 }
00385 else
00386 ypos = 0;
00387 rawypos = newypos;
00388 cnt += sizeof(short);
00389
00390 angle = (short)
00391 rint(((short)(buffer[cnt] | (buffer[cnt+1] << 8))) *
00392 PlayerRobotParams[param_idx].AngleConvFactor * 180.0/M_PI);
00393 cnt += sizeof(short);
00394
00395 lvel = (short)
00396 rint(((short)(buffer[cnt] | (buffer[cnt+1] << 8))) *
00397 PlayerRobotParams[param_idx].VelConvFactor);
00398 cnt += sizeof(short);
00399
00400 rvel = (short)
00401 rint(((short)(buffer[cnt] | (buffer[cnt+1] << 8))) *
00402 PlayerRobotParams[param_idx].VelConvFactor);
00403 cnt += sizeof(short);
00404
00405 battery = buffer[cnt];
00406 cnt += sizeof(unsigned char);
00407
00408 lwstall = buffer[cnt] & 0x01;
00409 rearbumpers = buffer[cnt] >> 1;
00410 cnt += sizeof(unsigned char);
00411
00412 rwstall = buffer[cnt] & 0x01;
00413 frontbumpers = buffer[cnt] >> 1;
00414 cnt += sizeof(unsigned char);
00415
00416 control = (short)
00417 rint(((short)(buffer[cnt] | (buffer[cnt+1] << 8))) *
00418 PlayerRobotParams[param_idx].AngleConvFactor);
00419 cnt += sizeof(short);
00420
00421 ptu = (buffer[cnt] | (buffer[cnt+1] << 8));
00422 cnt += sizeof(short);
00423
00424
00425 if(buffer[cnt] != 255 && buffer[cnt] != 0 && buffer[cnt] != 181)
00426 compass = (buffer[cnt]-1)*2;
00427 cnt += sizeof(unsigned char);
00428
00429 unsigned char numSonars=buffer[cnt];
00430 cnt+=sizeof(unsigned char);
00431
00432 if(numSonars>0)
00433 {
00434
00435 unsigned char maxSonars=sonarreadings;
00436 for(unsigned char i=0;i<numSonars;i++)
00437 {
00438 unsigned char sonarIndex=buffer[cnt+i*(sizeof(unsigned char)+sizeof(unsigned short))];
00439 if((sonarIndex+1)>maxSonars) maxSonars=sonarIndex+1;
00440 }
00441
00442
00443 if(maxSonars>sonarreadings)
00444 {
00445 unsigned short *newSonars=new unsigned short[maxSonars];
00446 for(unsigned char i=0;i<sonarreadings;i++)
00447 newSonars[i]=sonars[i];
00448 if(sonars!=NULL) delete[] sonars;
00449 sonars=newSonars;
00450 sonarreadings=maxSonars;
00451 }
00452
00453
00454 for(unsigned char i=0;i<numSonars;i++)
00455 {
00456 sonars[buffer[cnt]]= (unsigned short)
00457 rint((buffer[cnt+1] | (buffer[cnt+2] << 8)) *
00458 PlayerRobotParams[param_idx].RangeConvFactor);
00459 cnt+=sizeof(unsigned char)+sizeof(unsigned short);
00460 }
00461 }
00462
00463 timer = (buffer[cnt] | (buffer[cnt+1] << 8));
00464 cnt += sizeof(short);
00465
00466 analog = buffer[cnt];
00467 cnt += sizeof(unsigned char);
00468
00469 digin = buffer[cnt];
00470 cnt += sizeof(unsigned char);
00471
00472 digout = buffer[cnt];
00473 cnt += sizeof(unsigned char);
00474
00475
00476 }
00477
00478
00488 void SIP::ParseSERAUX( unsigned char *buffer )
00489 {
00490 unsigned char type = buffer[1];
00491 if (type != SERAUX && type != SERAUX2)
00492 {
00493
00494 printf("ERROR: Attempt to parse non SERAUX packet as serial data.\n");
00495 return;
00496 }
00497
00498 int len = (int)buffer[0]-3;
00499
00500
00501
00502
00503
00504
00505
00506
00507 int ix;
00508 for (ix = (len>18 ? len-17 : 2); ix<=len-8; ix++)
00509 if (buffer[ix] == 255)
00510 break;
00511 if (len < 10 || ix > len-8) {
00512 printf("ERROR: Failed to get a full blob tracking packet.\n");
00513 return;
00514 }
00515
00516
00517 if (buffer[ix+1] == 'S')
00518 {
00519
00520 printf("Tracking color (RGB): %d %d %d\n"
00521 " with variance: %d %d %d\n",
00522 buffer[ix+2], buffer[ix+3], buffer[ix+4],
00523 buffer[ix+5], buffer[ix+6], buffer[ix+7]);
00524 blobcolor = buffer[ix+2]<<16 | buffer[ix+3]<<8 | buffer[ix+4];
00525 return;
00526 }
00527
00528
00529 if (buffer[ix+1] == 'M')
00530 {
00531
00532 blobmx = buffer[ix+2];
00533 blobmy = buffer[ix+3];
00534 blobx1 = buffer[ix+4];
00535 bloby1 = buffer[ix+5];
00536 blobx2 = buffer[ix+6];
00537 bloby2 = buffer[ix+7];
00538 blobconf = buffer[ix+9];
00539
00540 blobarea = (bloby2 - bloby1 +1)*(blobx2 - blobx1 + 1)*blobconf/255;
00541 return;
00542 }
00543
00544 printf("ERROR: Unknown blob tracker packet type: %c\n", buffer[ix+1]);
00545 return;
00546 }
00547
00548
00549
00550
00551
00552
00553
00554 void
00555 SIP::ParseGyro(unsigned char* buffer)
00556 {
00557
00558
00559 int len = (int)buffer[0]-3;
00560
00561 unsigned char type = buffer[1];
00562 if(type != GYROPAC)
00563 {
00564
00565 PLAYER_ERROR("ERROR: Attempt to parse non GYRO packet as gyro data.\n");
00566 return;
00567 }
00568
00569 if(len < 1)
00570 {
00571 PLAYER_WARN("Couldn't get gyro measurement count");
00572 return;
00573 }
00574
00575
00576 int count = (int)buffer[2];
00577
00578
00579 if((len-1) != (count*3))
00580 {
00581 PLAYER_WARN("Mismatch between gyro measurement count and packet length");
00582 return;
00583 }
00584
00585
00586
00587
00588
00589
00590
00591 float ratesum = 0;
00592 int bufferpos = 3;
00593 unsigned short rate;
00594 unsigned char temp;
00595 for(int i=0; i<count; i++)
00596 {
00597 rate = (unsigned short)(buffer[bufferpos++]);
00598 rate |= buffer[bufferpos++] << 8;
00599 temp = bufferpos++;
00600
00601 ratesum += rate;
00602 }
00603
00604 int32_t average_rate = (int32_t)rint(ratesum / (float)count);
00605
00606
00607 gyro_rate = average_rate;
00608 }
00609
00610 void SIP::ParseArm (unsigned char *buffer)
00611 {
00612 int length = (int) buffer[0] - 2;
00613
00614 if (buffer[1] != ARMPAC)
00615 {
00616 PLAYER_ERROR ("ERROR: Attempt to parse a non ARM packet as arm data.\n");
00617 return;
00618 }
00619
00620 if (length < 1 || length != 9)
00621 {
00622 PLAYER_WARN ("ARMpac length incorrect size");
00623 return;
00624 }
00625
00626 unsigned char status = buffer[2];
00627 if (status & 0x01)
00628 armPowerOn = true;
00629 else
00630 armPowerOn = false;
00631
00632 if (status & 0x02)
00633 armConnected = true;
00634 else
00635 armConnected = false;
00636
00637 unsigned char motionStatus = buffer[3];
00638 if (motionStatus & 0x01)
00639 armJointMoving[0] = true;
00640 if (motionStatus & 0x02)
00641 armJointMoving[1] = true;
00642 if (motionStatus & 0x04)
00643 armJointMoving[2] = true;
00644 if (motionStatus & 0x08)
00645 armJointMoving[3] = true;
00646 if (motionStatus & 0x10)
00647 armJointMoving[4] = true;
00648 if (motionStatus & 0x20)
00649 armJointMoving[5] = true;
00650
00651 memcpy (armJointPos, &buffer[4], 6);
00652 memset (armJointPosRads, 0, 6 * sizeof (double));
00653 }
00654
00655 void SIP::ParseArmInfo (unsigned char *buffer)
00656 {
00657 int length = (int) buffer[0] - 2;
00658 if (buffer[1] != ARMINFOPAC)
00659 {
00660 PLAYER_ERROR ("ERROR: Attempt to parse a non ARMINFO packet as arm info.\n");
00661 return;
00662 }
00663
00664 if (length < 1)
00665 {
00666 PLAYER_WARN ("ARMINFOpac length bad size");
00667 return;
00668 }
00669
00670
00671 if (armVersionString)
00672 free (armVersionString);
00673
00674
00675 armVersionString = (char*)calloc(length+1,sizeof(char));
00676 assert(armVersionString);
00677 strncpy(armVersionString,(char*)&buffer[2], length);
00678 int dataOffset = strlen (armVersionString) + 3;
00679
00680 armNumJoints = buffer[dataOffset];
00681 if (armJoints)
00682 delete[] armJoints;
00683 if (armNumJoints <= 0)
00684 return;
00685 armJoints = new ArmJoint[armNumJoints];
00686 dataOffset += 1;
00687 for (int ii = 0; ii < armNumJoints; ii++)
00688 {
00689 armJoints[ii].speed = buffer[dataOffset + (ii * 6)];
00690 armJoints[ii].home = buffer[dataOffset + (ii * 6) + 1];
00691 armJoints[ii].min = buffer[dataOffset + (ii * 6) + 2];
00692 armJoints[ii].centre = buffer[dataOffset + (ii * 6) + 3];
00693 armJoints[ii].max = buffer[dataOffset + (ii * 6) + 4];
00694 armJoints[ii].ticksPer90 = buffer[dataOffset + (ii * 6) + 5];
00695 }
00696 }