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
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Devices/BeeStem3.H"
00039
00040 #include "Component/OptionManager.H"
00041 #include <string>
00042
00043 #define BS_CMD_DELAY 5000000
00044
00045
00046 BeeStem3::BeeStem3(OptionManager& mgr, const std::string& descrName,
00047 const std::string& tagName, const char *defdev) :
00048 ModelComponent(mgr, descrName, tagName),
00049 itsPort(new Serial(mgr))
00050 {
00051
00052 itsPort->configure(defdev, 57600, "8N1", false, false, 1);
00053
00054
00055
00056 addSubComponent(itsPort);
00057
00058 mMotorControllerState.resize(NUM_MOTOR_CONTROLLERS);
00059
00060 for(int i = 0; i < mMotorControllerState.size(); i ++)
00061 {
00062 mMotorControllerState[i] = 0;
00063 }
00064
00065 pthread_mutex_init(&itsSerialLock, NULL);
00066 }
00067
00068
00069 BeeStem3::~BeeStem3()
00070 {
00071 pthread_mutex_destroy(&itsSerialLock);
00072 }
00073
00074
00075 bool BeeStem3::getSensors(int &accelX,int &accelY,int &accelZ,
00076 int &compassHeading, int &compassPitch, int &compassRoll,
00077 int &internalPressure, int &externalPressure,
00078 int &desiredHeading, int &desiredDepth, int &desiredSpeed,
00079 int &headingK, int &headingP, int &headingD, int &headingI, int &headingOutput,
00080 int &depthK, int &depthP, int &depthD, int &depthI, int &depthOutput, char &killSwitch)
00081
00082
00083 {
00084 char readCmd = 0x00;
00085 char accel_data[3];
00086 unsigned char adc_data[32];
00087 char desired_heading[2];
00088 char desired_depth[2];
00089 char desired_speed;
00090 char marker_drop[2];
00091 char comp_accel[6];
00092 char comp_mag[6];
00093 char comp_heading[6];
00094 char comp_tilt[6];
00095 char battery[4];
00096 char pid[12];
00097 char kill_switch;
00098 char temp;
00099
00100
00101
00102 while(itsPort->read(&temp,1));
00103
00104
00105 itsPort->write(&readCmd, 1);
00106 usleep(40000);
00107
00108
00109 int size = itsPort->read(&accel_data, 3);
00110
00111 if(size <= 0)
00112 {
00113 LERROR("Couldn't read accel_data.");
00114 return false;
00115 }
00116
00117 accelX = accel_data[0];
00118 accelY = accel_data[1];
00119 accelZ = accel_data[2];
00120
00121
00122 size = itsPort->read(&adc_data, 32);
00123
00124 if(size <= 0)
00125 {
00126 LERROR("Couldn't read adc_data.");
00127 return false;
00128 }
00129
00130 internalPressure = adc_data[14];
00131 internalPressure += adc_data[15]<<8;
00132
00133 externalPressure = adc_data[12];
00134 externalPressure += adc_data[13]<<8;
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 size = itsPort->read(&desired_heading, 2);
00156
00157 if(size <= 0)
00158 {
00159 LERROR("Couldn't read desired_heading.");
00160 return false;
00161 }
00162
00163 desiredHeading = desired_heading[0];
00164 desiredHeading += desired_heading[1]<<8;
00165
00166
00167 size = itsPort->read(&desired_depth, 2);
00168
00169 if(size <= 0)
00170 {
00171 LERROR("Couldn't read desired_depth.");
00172 return false;
00173 }
00174
00175 desiredDepth = (255 & desired_depth[0]);
00176 desiredDepth |= (255 & desired_depth[1]<<8) & 65280;
00177
00178
00179 size = itsPort->read(&desired_speed, 1);
00180
00181 if(size <= 0)
00182 {
00183 LERROR("Couldn't read desired_speed.");
00184 return false;
00185 }
00186
00187 desiredSpeed = desired_speed;
00188
00189
00190 size = itsPort->read(&marker_drop, 2);
00191
00192 if(size <= 0)
00193 {
00194 LERROR("Couldn't read marker_drop.");
00195 return false;
00196 }
00197
00198
00199 size = itsPort->read(&comp_accel, 6);
00200
00201 if(size <= 0)
00202 {
00203 LERROR("Couldn't read comp_accel.");
00204 return false;
00205 }
00206
00207
00208 size = itsPort->read(&comp_mag, 6);
00209
00210 if(size <= 0)
00211 {
00212 LERROR("Couldn't read comp_mag.");
00213 return false;
00214 }
00215
00216
00217 size = itsPort->read(&comp_heading, 6);
00218
00219 if(size <= 0)
00220 {
00221 LERROR("Couldn't read comp_heading.");
00222 return false;
00223 }
00224
00225
00226 compassHeading = (unsigned char) comp_heading[0];
00227 compassHeading += (unsigned char) (comp_heading[1])<<8;
00228
00229 compassPitch = comp_heading[2];
00230 compassPitch += comp_heading[3]<<8;
00231
00232 compassRoll = comp_heading[4];
00233 compassRoll += comp_heading[5]<<8;
00234
00235
00236 size = itsPort->read(&comp_tilt, 6);
00237
00238 if(size <= 0)
00239 {
00240 LERROR("Couldn't read comp_tilt.");
00241 return false;
00242 }
00243
00244
00245 size = itsPort->read(&battery,4);
00246
00247 if(size <= 0)
00248 {
00249 LERROR("Couldn't read battery.");
00250 return false;
00251 }
00252
00253
00254 size = itsPort->read(&pid,12);
00255
00256 if(size <= 0)
00257 {
00258 LERROR("Couldn't read pid.");
00259 return false;
00260 }
00261
00262 headingK = pid[0];
00263 headingP = pid[1];
00264 headingD = pid[2];
00265 headingI = pid[3];
00266
00267 headingOutput = (0x00ff & pid[4]);
00268 headingOutput |= pid[5] << 8;
00269
00270 depthK = pid[6];
00271 depthP = pid[7];
00272 depthD = pid[8];
00273 depthI = pid[9];
00274 depthOutput = (0x00ff & pid[10]);
00275 depthOutput |= pid[11] << 8;
00276
00277
00278 size = itsPort->read(&kill_switch,1);
00279
00280 if(size <= 0)
00281 {
00282 LERROR("Couldn't read kill switch.");
00283 return false;
00284 }
00285
00286 killSwitch = kill_switch;
00287
00288
00289
00290
00291
00292
00293 return true;
00294 }
00295
00296 bool BeeStem3::setPID(int pidMode, float k, float p, float i, float d)
00297 {
00298 LINFO("pidMode: %d, k %f, p %f, i %f, %f",pidMode,k,p,i,d);
00299
00300 char pidCmdK;
00301 char pidCmdP;
00302 char pidCmdI;
00303 char pidCmdD;
00304 char pidDepthEn = 0x61;
00305 char pidHeadingEn = 0x60;
00306 char en = 0x01;
00307 char dis = 0x00;
00308
00309 int16 kv, pv, iv, dv;
00310 kv = k*100;
00311 pv = p*100;
00312 iv = i*100;
00313 dv = d*100;
00314
00315 char temp;
00316
00317
00318 while(itsPort->read(&temp,1));
00319
00320 switch(pidMode)
00321 {
00322 case PID_DEPTH:
00323 pidCmdK = 0x20;
00324 pidCmdP = 0x21;
00325 pidCmdI = 0x22;
00326 pidCmdD = 0x23;
00327 break;
00328 case PID_HEADING:
00329 pidCmdK = 0x30;
00330 pidCmdP = 0x31;
00331 pidCmdI = 0x32;
00332 pidCmdD = 0x33;
00333 break;
00334 case PID_DISABLE:
00335 LINFO("Disable PID.");
00336 itsPort->write(&pidDepthEn, 1);
00337 itsPort->write(&dis, 1);
00338 itsPort->write(&pidHeadingEn, 1);
00339 itsPort->write(&dis, 1);
00340 return true;
00341 break;
00342 case PID_ENABLE:
00343 LINFO("Enable PID.");
00344 itsPort->write(&pidDepthEn, 1);
00345 itsPort->write(&en, 1);
00346
00347
00348 return true;
00349 break;
00350 default:
00351 LERROR("Invalid PID mode specified.");
00352 return false;
00353 }
00354
00355
00356
00357 itsPort->write(&pidCmdK, 1);
00358
00359 temp =(kv & 0xff00) >> 8;
00360 itsPort->write(&temp,1);
00361 temp =(kv & 0x00ff);
00362 itsPort->write(&temp,1);
00363
00364
00365 itsPort->write(&pidCmdP, 1);
00366 temp =(pv & 0xff00) >> 8;
00367 itsPort->write(&temp,1);
00368 temp =(pv & 0x00ff);
00369 itsPort->write(&temp,1);
00370
00371
00372 itsPort->write(&pidCmdI, 1);
00373 temp =(iv & 0xff00) >> 8;
00374 itsPort->write(&temp,1);
00375 temp =(iv & 0x00ff);
00376 itsPort->write(&temp,1);
00377
00378
00379 itsPort->write(&pidCmdD, 1);
00380 temp =(dv & 0xff00) >> 8;
00381 itsPort->write(&temp,1);
00382 temp =(dv & 0x00ff);
00383 itsPort->write(&temp,1);
00384
00385 return true;
00386 }
00387
00388 void BeeStem3::setThruster(int num, int val)
00389 {
00390 if(val == mMotorControllerState[num])
00391 {
00392 return;
00393 }
00394 mMotorControllerState[num] = val;
00395 printf("Set thruster [%d]:%d\n", num, val);
00396 char thrusterCmd = 0xff;
00397
00398
00399
00400
00401
00402
00403 itsPort->write(&thrusterCmd, 1);
00404
00405
00406
00407
00408
00409
00410 itsPort->write(&num, 1);
00411
00412
00413
00414
00415
00416 itsPort->write(&val, 1);
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 bool BeeStem3::setDesiredHeading(int16 heading)
00456 {
00457 char setDesiredHeadingCmd = 0x0b;
00458 char temp;
00459
00460
00461 while(itsPort->read(&temp,1));
00462
00463
00464 itsPort->write(&setDesiredHeadingCmd, 1);
00465
00466 char headingUpper = ((0x00ff00 & heading) >> 8) & 0x00ff;
00467 char headingLower = (heading & 0x00ff);
00468
00469 LINFO("Writing Heading Upper %x", headingUpper);
00470 itsPort->write(&headingUpper,1);
00471 LINFO("Writing Heading Lower %x", headingLower);
00472 itsPort->write(&headingLower,1);
00473
00474 return true;
00475 }
00476
00477 bool BeeStem3::setDesiredDepth(int16 depth)
00478 {
00479 char setDesiredDepthCmd = 0x0c;
00480 char temp;
00481
00482
00483 while(itsPort->read(&temp,1));
00484
00485
00486 itsPort->write(&setDesiredDepthCmd, 1);
00487
00488 char depthUpper = ((0x00ff00 & depth) >> 8) & 0x00ff;
00489 char depthLower = (depth & 0x00ff);
00490
00491 LINFO("Writing Depth Upper %x", depthUpper);
00492 itsPort->write(&depthUpper,1);
00493 LINFO("Writing Depth Lower %x", depthLower);
00494 itsPort->write(&depthLower,1);
00495
00496 return true;
00497 }
00498
00499 bool BeeStem3::setDesiredSpeed(char speed)
00500 {
00501 char setDesiredSpeedCmd = 0x0d;
00502 char temp;
00503
00504
00505 while(itsPort->read(&temp,1));
00506
00507
00508 itsPort->write(&setDesiredSpeedCmd, 1);
00509
00510 LINFO("Setting speed: %d\n",speed);
00511 itsPort->write(&speed,1);
00512
00513 return true;
00514 }
00515
00516 void BeeStem3::startCompassCalibration()
00517 {
00518 char startCalibCmd = 0xe0;
00519 char temp;
00520
00521
00522 while(itsPort->read(&temp,1));
00523
00524
00525 itsPort->write(&startCalibCmd, 1);
00526 }
00527
00528 void BeeStem3::endCompassCalibration()
00529 {
00530 char endCalibCmd = 0xe1;
00531 char temp;
00532
00533
00534 while(itsPort->read(&temp,1));
00535
00536
00537 itsPort->write(&endCalibCmd, 1);
00538 }
00539
00540
00541
00542
00543
00544