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 #include <rflex/rflex_driver.h>
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <netinet/in.h>
00031 #include <termios.h>
00032 #include <sys/stat.h>
00033 #include <iostream>
00034 #include <unistd.h>
00035 #include <string.h>
00036 #include <fcntl.h>
00037
00038
00039 static long sgn( long val ) {
00040 if (val < 0)
00041 return 0;
00042 else
00043 return 1;
00044 }
00045
00046 static unsigned int getInt16( const unsigned char *bytes ) {
00047 unsigned int i;
00048 memcpy( &i, bytes, 2 );
00049 return(htons(i));
00050 }
00051
00052
00053 static unsigned long getInt32( const unsigned char *bytes ) {
00054 unsigned long i;
00055 memcpy( &i, bytes, 4 );
00056 return(htonl(i));
00057 }
00058
00059
00060 static void putInt8( unsigned int i, unsigned char *bytes ) {
00061 memcpy( bytes, &i, 1 );
00062 }
00063
00064 static void putInt32( unsigned long l, unsigned char *bytes ) {
00065 uint32_t conv;
00066 conv = htonl( l );
00067 memcpy( bytes, &conv, 4 );
00068 }
00069
00070 RFLEX::RFLEX() {
00071 distance = bearing = transVelocity = rotVelocity = 0;
00072 voltage = 0;
00073 offset = 0;
00074 odomReady = 0;
00075 found = false;
00076 brake = true;
00077
00078
00079 lcdData=new unsigned char[320*240/8];
00080 if (lcdData != NULL) {
00081 lcdX=320/8;
00082 lcdY=240;
00083 }
00084 }
00085
00086 int RFLEX::initialize(const char* device_name) {
00087
00088 fd = open(device_name, O_RDWR | O_NONBLOCK);
00089 if (fd == -1) {
00090 fprintf(stderr,"Could not open serial port %s\n", device_name );
00091 return -1;
00092 }
00093
00094
00095 struct termios info;
00096 if (tcgetattr(fd, &info) < 0) {
00097 fprintf(stderr,"Could not get terminal information for %s\n", device_name );
00098 return -1;
00099 }
00100
00101
00102
00103 info.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG | BRKINT | ICRNL | INPCK | ISTRIP | IXON | CSIZE | PARENB | OPOST);
00104
00105
00106 info.c_cflag |= CS8;
00107
00108
00109 info.c_cc[VTIME] = 0;
00110 info.c_cc[VMIN] = 0;
00111 speed_t baud_rate = B115200;
00112 if (cfsetospeed(&info, baud_rate) < 0) {
00113 fprintf(stderr,"Could not set the output speed for %s\n", device_name );
00114 return -1;
00115 }
00116
00117 if (cfsetispeed(&info, baud_rate) < 0) {
00118 fprintf(stderr,"Could not set the input speed for %s\n", device_name );
00119 return -1;
00120 }
00121
00122
00123 if (tcsetattr(fd, TCSAFLUSH, &info) < 0) {
00124 close(fd);
00125 fprintf(stderr,"Could not set controls on serial port %s\n", device_name );
00126 }
00127
00128 pthread_mutex_init(&writeMutex, NULL);
00129 pthread_create(&thread, NULL, RFLEX::readThread, this);
00130
00131 return 0;
00132 }
00133
00134 RFLEX::~RFLEX() {
00135
00136 }
00137
00138 void RFLEX::configureSonar(const unsigned long echo_delay, const unsigned long ping_delay,
00139 const unsigned long set_delay, const unsigned long val) {
00140
00141 unsigned char data[MAX_COMMAND_LENGTH];
00142 putInt32( echo_delay, &(data[0]) );
00143 putInt32( ping_delay, &(data[4]) );
00144 putInt32( set_delay , &(data[8]) );
00145 putInt8( val, &(data[12]) );
00146 sendCommand(SONAR_PORT, 4, SONAR_RUN, 13, data );
00147 }
00148
00149 void RFLEX::setIrPower( const bool on ) {
00150 unsigned char data[MAX_COMMAND_LENGTH];
00151 long v1, v2, v3, v4, v5;
00152 unsigned char v6;
00153 if (on) {
00154 v1 = 0;
00155 v2 = 70;
00156 v3 = 10;
00157 v4 = 20;
00158 v5 = 150;
00159 v6 = 2;
00160 } else {
00161 v1 = v2 = v3 = v4 = v5 = 0;
00162 v6 = 0;
00163 }
00164
00165 putInt32( v1, &(data[0]) );
00166 putInt32( v2, &(data[4]) );
00167 putInt32( v3, &(data[8]) );
00168 putInt32( v4, &(data[12]) );
00169 putInt32( v5, &(data[16]) );
00170 putInt8( v6, &(data[20]) );
00171 sendCommand(IR_PORT, 0, IR_RUN, 21, data );
00172 }
00173
00174 void RFLEX::setBrakePower( const bool on ) {
00175 int brake;
00176 if (on)
00177 brake = MOT_BRAKE_SET;
00178 else
00179 brake = MOT_BRAKE_RELEASE;
00180
00181 sendCommand(MOT_PORT, 0, brake, 0, NULL );
00182 }
00183
00184 void RFLEX::motionSetDefaults( ) {
00185 sendCommand(MOT_PORT, 0, MOT_SET_DEFAULTS, 0, NULL );
00186 }
00187
00188 void RFLEX::setDigitalIoPeriod( const long period ) {
00189 unsigned char data[MAX_COMMAND_LENGTH];
00190 putInt32( period, &(data[0]) );
00191 sendCommand(DIO_PORT, 0, DIO_REPORTS_REQ, 4, data );
00192 }
00193
00194 void RFLEX::setOdometryPeriod( const long period ) {
00195 unsigned char data[MAX_COMMAND_LENGTH];
00196 long mask;
00197 if (period==0)
00198 mask = 0;
00199 else
00200 mask = 3;
00201
00202 putInt32( period, &(data[0]) );
00203 putInt32( mask, &(data[4]) );
00204 sendCommand(MOT_PORT, 0, MOT_SYSTEM_REPORT_REQ, 8, data );
00205 }
00206
00207 void RFLEX::setVelocity( const long tvel, const long rvel, const long acceleration) {
00208 long utvel =labs(tvel);
00209 long urvel =labs(rvel);
00210 unsigned char data[MAX_COMMAND_LENGTH];
00211
00212
00213
00214
00215
00216
00217
00218
00219 if((urvel&0xff00)==0x1b00){
00220
00221 urvel=(urvel&0xffff0000)|((urvel&0xff)>127?0x1c00:0x1aff);
00222 }
00223
00224
00225 if((urvel&0xff000000)==0x1b000000){
00226
00227 urvel=(urvel&0x00ffffff)|(((urvel&0xff0000)>>16)>127?0x1c000000:0x1aff0000);
00228 }
00229
00230
00231 putInt8( 0, &(data[0]) );
00232 putInt32( utvel, &(data[1]) );
00233 putInt32( acceleration, &(data[5]) );
00234 putInt32( STD_TRANS_TORQUE, &(data[9]) );
00235 putInt8( sgn(tvel), &(data[13]) );
00236
00237 sendCommand(MOT_PORT, 0, MOT_AXIS_SET_DIR, 14, data );
00238
00239 putInt8( 1, &(data[0]) );
00240 putInt32( urvel, &(data[1]) );
00241
00242 putInt32( STD_ROT_ACC, &(data[5]) );
00243 putInt32( STD_ROT_TORQUE, &(data[9]) );
00244 putInt8( sgn(rvel), &(data[13]) );
00245
00246 sendCommand(MOT_PORT, 0, MOT_AXIS_SET_DIR, 14, data );
00247 }
00248
00249 void RFLEX::sendSystemStatusCommand() {
00250 sendCommand(SYS_PORT, 0, SYS_STATUS, 0, NULL );
00251 }
00252
00253 void RFLEX::parseMotReport( const unsigned char* buffer ) {
00254 int rv, timeStamp, acc, trq;
00255 unsigned char axis;
00256
00257 switch (buffer[PACKET_OPCODE_BYTE]) {
00258 case MOT_SYSTEM_REPORT:
00259 rv = getInt32(&(buffer[6]));
00260 timeStamp = getInt32(&(buffer[10]));
00261 axis = buffer[14];
00262 if (axis == 0) {
00263 distance = getInt32(&(buffer[15]));
00264 transVelocity = getInt32(&(buffer[19]));
00265 odomReady = odomReady | 1;
00266 } else if (axis == 1) {
00267 bearing = getInt32(&(buffer[15]));
00268 rotVelocity = getInt32(&(buffer[19]));
00269 odomReady = odomReady | 2;
00270 }
00271 acc = getInt32(&(buffer[23]));
00272 trq = getInt32(&(buffer[27]));
00273 break;
00274 default:
00275 break;
00276 }
00277 }
00278
00279
00280 void RFLEX::parseDioReport( const unsigned char* buffer ) {
00281 unsigned long timeStamp;
00282 unsigned char length, address;
00283 unsigned short data;
00284 length = buffer[5];
00285
00286 switch (buffer[PACKET_OPCODE_BYTE]) {
00287 case DIO_REPORT:
00288 if (length < 6) {
00289 fprintf(stderr, "DIO Data Packet too small\n");
00290 break;
00291 }
00292 timeStamp = getInt32(&(buffer[6]));
00293 address = buffer[10];
00294 data = getInt16(&(buffer[11]));
00295 processDioEvent(address, data);
00296
00297 break;
00298 default:
00299 break;
00300 }
00301 }
00302
00303 void RFLEX::processDioEvent(unsigned char address, unsigned short data) {
00304 printf("DIO: address 0x%02x (%d) value 0x%02x (%d)\n", address, address, data, data);
00305 }
00306
00307
00308 void RFLEX::parseIrReport( const unsigned char* buffer ) {
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 #warning IR Unreported
00357
00358 }
00359
00360
00361
00362
00363 void RFLEX::parseSysReport( const unsigned char* buffer ) {
00364 unsigned long timeStamp;
00365 unsigned char length = buffer[5];
00366
00367
00368 switch (buffer[PACKET_OPCODE_BYTE]) {
00369 case SYS_LCD_DUMP:
00370
00371
00372 if (length < 6) {
00373 fprintf(stderr, "Got bad Sys packet (lcd)\n");
00374 break;
00375 }
00376
00377 unsigned char lcd_length, row;
00378 timeStamp=getInt32(&(buffer[6]));
00379 row = buffer[10];
00380 lcd_length = buffer[11];
00381 if (row > lcdY || lcd_length > lcdX) {
00382 fprintf(stderr,"LCD Data Overflow\n");
00383 break;
00384 }
00385
00386 memcpy(&lcdData[row*lcdX],&buffer[12],lcd_length);
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 break;
00410
00411 case SYS_STATUS:
00412 if (length < 9) {
00413 fprintf(stderr, "Got bad Sys packet (status)\n");
00414 break;
00415 }
00416 timeStamp=getInt32(&(buffer[6]));
00417
00418 voltage=getInt32(&(buffer[10]));
00419 brake=buffer[14];
00420
00421 break;
00422
00423 default:
00424 fprintf(stderr,"Unknown sys opcode recieved\n");
00425 }
00426 }
00427
00428
00429 void RFLEX::parseSonarReport( const unsigned char* buffer ) {
00430 int retval, timeStamp, count;
00431 unsigned char dlen = buffer[5];
00432
00433 switch (buffer[PACKET_OPCODE_BYTE]) {
00434 case SONAR_REPORT:
00435 retval = getInt32(&(buffer[6]));
00436 timeStamp = getInt32(&(buffer[10]));
00437 count = 0;
00438 while ((8+count*3<dlen) && (count<256) && (count < SONAR_MAX_COUNT)) {
00439 unsigned int sid = buffer[14+count*3];
00440 sonar_ranges[sid] = getInt16( &(buffer[14+count*3+1]) );
00441 count++;
00442 }
00443 break;
00444 default:
00445 break;
00446 }
00447 }
00448
00449
00450
00451 void RFLEX::parseJoyReport( const unsigned char* buffer ) {
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 #warning joystick control not implemented
00486
00487 }
00488
00489
00490
00491 void RFLEX::parsePacket( const unsigned char* buffer ) {
00492 switch (buffer[PACKET_PORT_BYTE]) {
00493 case SYS_PORT:
00494 parseSysReport( buffer );
00495 break;
00496 case MOT_PORT:
00497 parseMotReport( buffer );
00498 break;
00499 case JSTK_PORT:
00500 parseJoyReport( buffer );
00501 break;
00502 case SONAR_PORT:
00503 parseSonarReport( buffer );
00504 break;
00505 case DIO_PORT:
00506 parseDioReport( buffer );
00507 break;
00508 case IR_PORT:
00509 parseIrReport( buffer);
00510 break;
00511 default:
00512 break;
00513 }
00514 }
00515
00516
00517
00518
00519
00520
00521
00522 void* RFLEX::readThread(void *ptr) {
00523 RFLEX *rflex = static_cast<RFLEX *>(ptr);
00524
00525 while (rflex->fd>=0) {
00526
00527 fd_set read_set;
00528 FD_ZERO(&read_set);
00529 FD_SET(rflex->fd, &read_set);
00530
00531
00532 if (select(rflex->fd + 1, &read_set, NULL, NULL, NULL) < 0) {
00533
00534 } else if (FD_ISSET(rflex->fd, &read_set)) {
00535 rflex->readPacket();
00536 }
00537 }
00538 return NULL;
00539 }
00540
00541
00542 void RFLEX::readPacket() {
00543
00544 const int read_size = readData();
00545 if (read_size == 0)
00546 return;
00547
00548
00549 const int data_size = read_size - PROTOCOL_SIZE;
00550 if (readBuffer[PACKET_SIZE_BYTE] != data_size) {
00551
00552 for (int i = 0; i < BUFFER_SIZE; ++i) {
00553
00554
00555
00556 }
00557 }
00558
00559
00560 if (computeCRC(readBuffer + PACKET_CRC_START, data_size + PACKET_CRC_OFFSET) != readBuffer[data_size + PACKET_DATA_START_BYTE]) {
00561
00562
00563 for (int i = 0; i < BUFFER_SIZE; ++i) {
00564
00565
00566
00567 }
00568
00569
00570 unsigned char tdata = 0;
00571 while (tdata != ETX)
00572 while (read(fd, &tdata, 1) != 1) { }
00573
00574 return;
00575 }
00576
00577 parsePacket(readBuffer);
00578 }
00579
00580
00581 int RFLEX::readData() {
00582
00583
00584 int bRead = read(fd, readBuffer + offset, 1);
00585 if (bRead == 0)
00586 return 0;
00587 else if (bRead < 0) {
00588 printf("Error reading from port!\n");
00589 return 0;
00590 }
00591
00592
00593
00594 if (!found) {
00595
00596
00597 if (readBuffer[0] != ESC) {
00598 offset = 0;
00599 return 0;
00600 }
00601 if (offset == 0) {
00602 offset = 1;
00603 return 0;
00604 }
00605
00606
00607
00608 if (readBuffer[1] == STX) {
00609 found = true;
00610 offset = 2;
00611 return 0;
00612 } else if (readBuffer[1] == ESC) {
00613 offset = 1;
00614 return 0;
00615 } else {
00616 offset = 0;
00617 return 0;
00618 }
00619 } else {
00620
00621 if (readBuffer[offset - 1] == ESC) {
00622 switch (readBuffer[offset]) {
00623 case NUL:
00624 read(fd, readBuffer + offset, 1);
00625 ++offset;
00626 return 0;
00627 case SOH:
00628 --offset;
00629 return 0;
00630 case ETX:
00631 const int retval = offset + 1;
00632 found = false;
00633 offset = 0;
00634 return retval;
00635 };
00636 } else {
00637
00638 ++offset;
00639
00640 return 0;
00641 }
00642 }
00643
00644
00645 return 0;
00646 }
00647
00648
00649 bool RFLEX::sendCommand(const unsigned char port, const unsigned char id, const unsigned char opcode, const int length, unsigned char* data) {
00650 pthread_mutex_lock(&writeMutex);
00651
00652
00653 writeBuffer[0] = ESC;
00654 writeBuffer[1] = STX;
00655 writeBuffer[PACKET_PORT_BYTE] = port;
00656 writeBuffer[PACKET_ID_BYTE] = id;
00657 writeBuffer[PACKET_OPCODE_BYTE] = opcode;
00658 writeBuffer[PACKET_SIZE_BYTE] = static_cast<unsigned char>(length);
00659 for (int i=0; i<length; i++) {
00660 writeBuffer[6+i] = data[i];
00661 }
00662
00663 writeBuffer[length + PACKET_DATA_START_BYTE] = computeCRC(writeBuffer + PACKET_CRC_START, length + PACKET_CRC_OFFSET);
00664 writeBuffer[length + PACKET_DATA_START_BYTE + 1] = ESC;
00665 writeBuffer[length + PACKET_DATA_START_BYTE + 2] = ETX;
00666
00667 int ret = writePacket(length + 9);
00668 pthread_mutex_unlock(&writeMutex);
00669 return ret;
00670 }
00671
00672
00673 bool RFLEX::writePacket(const int length) const {
00674 if (fd<0)
00675 return false;
00676
00677 int bytes_written = 0;
00678
00679 while (bytes_written < length) {
00680 int n = write(fd, writeBuffer + bytes_written, length - bytes_written);
00681 if (n < 0)
00682 return false;
00683 else
00684 bytes_written += n;
00685
00686
00687 usleep(1000);
00688 }
00689
00690 return true;
00691 }
00692
00693 unsigned char RFLEX::computeCRC(const unsigned char *buffer, const int n) {
00694 int crc =buffer[0];
00695 for (int i = 1; i < n; ++i)
00696 crc ^= buffer[i];
00697 return crc;
00698 }
00699