OpenInterface.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 *
00003 * Software License Agreement (BSD License)
00004 *
00005 *  Copyright (c) 2010, ISR University of Coimbra.
00006 *  All rights reserved.
00007 *
00008 *  Redistribution and use in source and binary forms, with or without
00009 *  modification, are permitted provided that the following conditions
00010 *  are met:
00011 *
00012 *   * Redistributions of source code must retain the above copyright
00013 *     notice, this list of conditions and the following disclaimer.
00014 *   * Redistributions in binary form must reproduce the above
00015 *     copyright notice, this list of conditions and the following
00016 *     disclaimer in the documentation and/or other materials provided
00017 *     with the distribution.
00018 *   * Neither the name of the ISR University of Coimbra nor the names of its
00019 *     contributors may be used to endorse or promote products derived
00020 *     from this software without specific prior written permission.
00021 *
00022 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033 *  POSSIBILITY OF SUCH DAMAGE.
00034 *
00035 * Author: Gonçalo Cabrita on 19/05/2010
00036 *********************************************************************/
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <math.h>
00040 #include <stdio.h>
00041 #include <string>
00042 #include <netinet/in.h>
00043 #include <sys/types.h>
00044 
00045 #include "roomba_500_series/OpenInterface.h"
00046 
00047 // *****************************************************************************
00048 // Constructor
00049 irobot::OpenInterface::OpenInterface(const char * new_serial_port)
00050 {       
00051         port_name_ = new_serial_port;
00052 
00053         OImode_ = OI_MODE_OFF;
00054         
00055         this->resetOdometry();
00056         
00057         encoder_counts_[LEFT] = -1;
00058         encoder_counts_[RIGHT] = -1;
00059         
00060         last_encoder_counts_[LEFT] = 0;
00061         last_encoder_counts_[RIGHT] = 0;
00062         
00063         num_of_packets_ = 0;
00064         sensor_packets_ = NULL;
00065         packets_size_ = 0;
00066         
00067         // Default packets
00068         OI_Packet_ID default_packets[2] = {OI_PACKET_RIGHT_ENCODER, OI_PACKET_LEFT_ENCODER};
00069         this->setSensorPackets(default_packets, 2, OI_PACKET_RIGHT_ENCODER_SIZE + OI_PACKET_LEFT_ENCODER_SIZE);
00070 
00071         serial_port_ = new cereal::CerealPort();
00072 }
00073 
00074 
00075 // *****************************************************************************
00076 // Destructor
00077 irobot::OpenInterface::~OpenInterface()
00078 {
00079         // Clean up!
00080         delete serial_port_;
00081 }
00082 
00083 
00084 // *****************************************************************************
00085 // Open the serial port
00086 int irobot::OpenInterface::openSerialPort(bool full_control)
00087 {
00088         try{ serial_port_->open(port_name_.c_str(), 115200); }
00089         catch(cereal::Exception& e){ return(-1); }
00090 
00091         this->startOI(full_control);
00092 
00093         return(0);
00094 }
00095 
00096 
00097 // *****************************************************************************
00098 // Set the mode
00099 int irobot::OpenInterface::startOI(bool full_control)
00100 {       
00101         char buffer[1];
00102 
00103         usleep(OI_DELAY_MODECHANGE_MS * 1e3);
00104         buffer[0] = (char)OI_OPCODE_START;
00105         try{ serial_port_->write(buffer, 1); }
00106         catch(cereal::Exception& e){ return(-1); }
00107         OImode_ = OI_MODE_PASSIVE;
00108 
00109         usleep(OI_DELAY_MODECHANGE_MS * 1e3);
00110         buffer[0] = (char)OI_OPCODE_CONTROL;
00111         try{ serial_port_->write(buffer, 1); }
00112         catch(cereal::Exception& e){ return(-1); }
00113         OImode_ = OI_MODE_SAFE;
00114         
00115         if(full_control)
00116         {
00117                 usleep(OI_DELAY_MODECHANGE_MS * 1e3);
00118                 buffer[0] = (char)OI_OPCODE_FULL;
00119                 try{ serial_port_->write(buffer, 1); }
00120                 catch(cereal::Exception& e){ return(-1); }
00121                 OImode_ = OI_MODE_FULL;
00122         }
00123         return(0);
00124 }
00125 
00126 
00127 // *****************************************************************************
00128 // Close the serial port
00129 int irobot::OpenInterface::closeSerialPort()
00130 {
00131         this->drive(0.0, 0.0);
00132         usleep(OI_DELAY_MODECHANGE_MS * 1e3);
00133 
00134         try{ serial_port_->close(); }
00135         catch(cereal::Exception& e){ return(-1); }
00136 
00137         return(0);
00138 }
00139 
00140 
00141 // *****************************************************************************
00142 // Send an OP code to the roomba
00143 int irobot::OpenInterface::sendOpcode(OI_Opcode code)
00144 {
00145         char to_send = code;
00146         try{ serial_port_->write(&to_send, 1); }
00147         catch(cereal::Exception& e){ return(-1); }
00148         return(0);
00149 }
00150 
00151 
00152 // *****************************************************************************
00153 // Power down the roomba
00154 int irobot::OpenInterface::powerDown()
00155 {
00156         return sendOpcode(OI_OPCODE_POWER);
00157 }
00158 
00159 
00160 // *****************************************************************************
00161 // Set the speeds
00162 int irobot::OpenInterface::drive(double linear_speed, double angular_speed)
00163 {
00164         int left_speed_mm_s = (int)((linear_speed-ROOMBA_AXLE_LENGTH*angular_speed/2)*1e3);             // Left wheel velocity in mm/s
00165         int right_speed_mm_s = (int)((linear_speed+ROOMBA_AXLE_LENGTH*angular_speed/2)*1e3);    // Right wheel velocity in mm/s
00166         
00167         return this->driveDirect(left_speed_mm_s, right_speed_mm_s);
00168 }
00169 
00170 
00171 // *****************************************************************************
00172 // Set the motor speeds
00173 int irobot::OpenInterface::driveDirect(int left_speed, int right_speed)
00174 {
00175         // Limit velocity
00176         int16_t left_speed_mm_s = MAX(left_speed, -ROOMBA_MAX_LIN_VEL_MM_S);
00177         left_speed_mm_s = MIN(left_speed, ROOMBA_MAX_LIN_VEL_MM_S);
00178         int16_t right_speed_mm_s = MAX(right_speed, -ROOMBA_MAX_LIN_VEL_MM_S);
00179         right_speed_mm_s = MIN(right_speed, ROOMBA_MAX_LIN_VEL_MM_S);
00180         
00181         // Compose comand
00182         char cmd_buffer[5];
00183         cmd_buffer[0] = (char)OI_OPCODE_DRIVE_DIRECT;
00184         cmd_buffer[1] = (char)(right_speed_mm_s >> 8);
00185         cmd_buffer[2] = (char)(right_speed_mm_s & 0xFF);
00186         cmd_buffer[3] = (char)(left_speed_mm_s >> 8);
00187         cmd_buffer[4] = (char)(left_speed_mm_s & 0xFF);
00188 
00189         try{ serial_port_->write(cmd_buffer, 5); }
00190         catch(cereal::Exception& e){ return(-1); }
00191 
00192         return(0);
00193 }
00194 
00195 
00196 // *****************************************************************************
00197 // Set the motor PWMs
00198 int irobot::OpenInterface::drivePWM(int left_pwm, int right_pwm)
00199 {
00200         // TODO: Not yet implemented... Doesnt really matter.
00201         return(-1);
00202 }
00203 
00204 
00205 // *****************************************************************************
00206 // Set the brushes motors status
00207 int irobot::OpenInterface::brushes(unsigned char side_brush, unsigned char vacuum, unsigned char main_brush, unsigned char side_brush_clockwise, unsigned char main_brush_dir)
00208 {
00209         unsigned char cmd_buffer[2];
00210         cmd_buffer[0] = OI_OPCODE_MOTORS;
00211         cmd_buffer[1] = side_brush | vacuum<<1 | main_brush<<2 | side_brush_clockwise<<3 | main_brush_dir<<4;
00212         
00213         try{ serial_port_->write((char*)cmd_buffer, 2); }
00214         catch(cereal::Exception& e){ return(-1); }
00215         return(0);
00216 }
00217 
00218 // *****************************************************************************
00219 // Set the brushes motors PWMs
00220 int irobot::OpenInterface::brushesPWM(char main_brush, char side_brush, char vacuum)
00221 {
00222         char cmd_buffer[4];
00223         cmd_buffer[0] = (char)OI_OPCODE_PWM_MOTORS;
00224         cmd_buffer[1] = main_brush;
00225         cmd_buffer[2] = side_brush;
00226         cmd_buffer[3] = vacuum<0 ? 0 : vacuum;
00227 
00228         try{ serial_port_->write(cmd_buffer, 4); }
00229         catch(cereal::Exception& e){ return(-1); }
00230         return(0);
00231 }
00232 
00233 
00234 // *****************************************************************************
00235 // Set the sensors to read
00236 int irobot::OpenInterface::setSensorPackets(OI_Packet_ID * new_sensor_packets, int new_num_of_packets, size_t new_buffer_size)
00237 {
00238         if(sensor_packets_ == NULL)
00239         {
00240                 delete [] sensor_packets_;
00241         }
00242         
00243         num_of_packets_ = new_num_of_packets;
00244         sensor_packets_ = new OI_Packet_ID[num_of_packets_];
00245         
00246         for(int i=0 ; i<num_of_packets_ ; i++)
00247         {
00248                 sensor_packets_[i] = new_sensor_packets[i];
00249         }
00250 
00251         stream_defined_ = false;
00252         packets_size_ = new_buffer_size;
00253         return(0);
00254 }
00255 
00256 
00257 // *****************************************************************************
00258 // Read the sensors
00259 int irobot::OpenInterface::getSensorPackets(int timeout)
00260 {
00261         char cmd_buffer[num_of_packets_+2];
00262         char data_buffer[packets_size_];
00263 
00264         // Fill in the command buffer to send to the robot
00265         cmd_buffer[0] = (char)OI_OPCODE_QUERY;                  // Query
00266         cmd_buffer[1] = num_of_packets_;                                // Number of packets
00267         for(int i=0 ; i<num_of_packets_ ; i++)
00268         {
00269                 cmd_buffer[i+2] = sensor_packets_[i];           // The packet IDs
00270         }
00271 
00272         try{ serial_port_->write(cmd_buffer, num_of_packets_+2); }
00273         catch(cereal::Exception& e){ return(-1); }
00274         
00275         try{ serial_port_->readBytes(data_buffer, packets_size_, timeout); }
00276         catch(cereal::Exception& e){ return(-1); }
00277         
00278         return this->parseSensorPackets((unsigned char*)data_buffer, packets_size_);
00279 }
00280 
00281 
00282 // *****************************************************************************
00283 // Read the sensors stream
00284 int irobot::OpenInterface::streamSensorPackets()
00285 {
00286         char data_buffer[packets_size_];
00287 
00288         if(!stream_defined_)
00289         {
00290                 char cmd_buffer[num_of_packets_+2];
00291 
00292                 // Fill in the command buffer to send to the robot
00293                 cmd_buffer[0] = (char)OI_OPCODE_STREAM;                 // Stream
00294                 cmd_buffer[1] = num_of_packets_;                                // Number of packets
00295                 for(int i=0 ; i<num_of_packets_ ; i++)
00296                 {
00297                         cmd_buffer[i+2] = sensor_packets_[i];           // The packet IDs
00298                 }
00299                 try{ serial_port_->write(cmd_buffer, num_of_packets_+2); }
00300                 catch(cereal::Exception& e){ return(-1); }
00301                 stream_defined_ = true;
00302         }
00303         try{ serial_port_->readBytes(data_buffer, packets_size_, 100); }
00304         catch(cereal::Exception& e){ return(-1); }
00305         
00306         return this->parseSensorPackets((unsigned char*)data_buffer, packets_size_);
00307 }
00308 
00309 int irobot::OpenInterface::startStream()
00310 {
00311         char data_buffer[2];
00312 
00313         data_buffer[0] = OI_OPCODE_PAUSE_RESUME_STREAM;
00314         data_buffer[1] = 1;
00315 
00316         try{ serial_port_->write(data_buffer, 2); }
00317         catch(cereal::Exception& e){ return(-1); }
00318         return(0);
00319 }
00320 
00321 int irobot::OpenInterface::stopStream()
00322 {
00323         char data_buffer[2];
00324 
00325         data_buffer[0] = OI_OPCODE_PAUSE_RESUME_STREAM;
00326         data_buffer[1] = 0;
00327 
00328         try{ serial_port_->write(data_buffer, 2); }
00329         catch(cereal::Exception& e){ return(-1); }
00330         return(0);
00331 }
00332 
00333 
00334 // *****************************************************************************
00335 // Parse sensor data
00336 int irobot::OpenInterface::parseSensorPackets(unsigned char * buffer , size_t buffer_lenght)
00337 {       
00338         if(buffer_lenght != packets_size_)
00339         {
00340                 // Error wrong packet size
00341                 return(-1);
00342         }
00343 
00344         int i = 0;
00345         unsigned int index = 0;
00346         while(index < packets_size_)
00347         {
00348                 if(sensor_packets_[i]==OI_PACKET_GROUP_0)               // PACKETS 7-26
00349                 {
00350                         index += parseBumpersAndWheeldrops(buffer, index);
00351                         index += parseWall(buffer, index);
00352                         index += parseLeftCliff(buffer, index);
00353                         index += parseFrontLeftCliff(buffer, index);
00354                         index += parseFrontRightCliff(buffer, index);
00355                         index += parseRightCliff(buffer, index);
00356                         index += parseVirtualWall(buffer, index);
00357                         index += parseOvercurrents(buffer, index);
00358                         index += parseDirtDetector(buffer, index);
00359                         index ++;       // Unused byte
00360                         index += parseIrOmniChar(buffer, index);
00361                         index += parseButtons(buffer, index);
00362                         index += parseDistance(buffer, index);
00363                         index += parseAngle(buffer, index);
00364                         index += parseChargingState(buffer, index);
00365                         index += parseVoltage(buffer, index);
00366                         index += parseCurrent(buffer, index);
00367                         index += parseTemperature(buffer, index);
00368                         index += parseBatteryCharge(buffer, index);
00369                         index += parseBatteryCapacity(buffer, index);
00370                         i++;
00371                 }
00372                 if(sensor_packets_[i]==OI_PACKET_GROUP_1)               // PACKETS 7-16
00373                 {
00374                         index += parseBumpersAndWheeldrops(buffer, index);
00375                         index += parseWall(buffer, index);
00376                         index += parseLeftCliff(buffer, index);
00377                         index += parseFrontLeftCliff(buffer, index);
00378                         index += parseFrontRightCliff(buffer, index);
00379                         index += parseRightCliff(buffer, index);
00380                         index += parseVirtualWall(buffer, index);
00381                         index += parseOvercurrents(buffer, index);
00382                         index += parseDirtDetector(buffer, index);
00383                         index ++;       // Unused byte
00384                         i++;
00385                 }
00386                 if(sensor_packets_[i]==OI_PACKET_GROUP_2)               // PACKETS 17-20
00387                 {
00388                         index += parseIrOmniChar(buffer, index);
00389                         index += parseButtons(buffer, index);
00390                         index += parseDistance(buffer, index);
00391                         index += parseAngle(buffer, index);
00392                         i++;
00393                 }
00394                 if(sensor_packets_[i]==OI_PACKET_GROUP_3)               // PACKETS 21-26
00395                 {
00396                         index += parseChargingState(buffer, index);
00397                         index += parseVoltage(buffer, index);
00398                         index += parseCurrent(buffer, index);
00399                         index += parseTemperature(buffer, index);
00400                         index += parseBatteryCharge(buffer, index);
00401                         index += parseBatteryCapacity(buffer, index);
00402                         i++;
00403                 }
00404                 if(sensor_packets_[i]==OI_PACKET_GROUP_4)               // PACKETS 27-34
00405                 {
00406                         index += parseWallSignal(buffer, index);
00407                         index += parseLeftCliffSignal(buffer, index);
00408                         index += parseFrontLeftCliffSignal(buffer, index);
00409                         index += parseFontRightCliffSignal(buffer, index);
00410                         index += parseRightCliffSignal(buffer, index);
00411                         index += 3;     // Unused bytes
00412                         index += parseChargingSource(buffer, index);
00413                         i++;
00414                 }
00415                 if(sensor_packets_[i]==OI_PACKET_GROUP_5)               // PACKETS 35-42
00416                 {
00417                         index += parseOiMode(buffer, index);
00418                         index += parseSongNumber(buffer, index);
00419                         index += parseSongPlaying(buffer, index);
00420                         index += parseNumberOfStreamPackets(buffer, index);
00421                         index += parseRequestedVelocity(buffer, index);
00422                         index += parseRequestedRadius(buffer, index);
00423                         index += parseRequestedRightVelocity(buffer, index);
00424                         index += parseRequestedLeftVelocity(buffer, index);
00425                         i++;
00426                 }
00427                 if(sensor_packets_[i]==OI_PACKET_GROUP_6)               // PACKETS 7-42
00428                 {
00429                         index += parseBumpersAndWheeldrops(buffer, index);
00430                         index += parseWall(buffer, index);
00431                         index += parseLeftCliff(buffer, index);
00432                         index += parseFrontLeftCliff(buffer, index);
00433                         index += parseFrontRightCliff(buffer, index);
00434                         index += parseRightCliff(buffer, index);
00435                         index += parseVirtualWall(buffer, index);
00436                         index += parseOvercurrents(buffer, index);
00437                         index += parseDirtDetector(buffer, index);
00438                         index ++;       // Unused byte
00439                         index += parseIrOmniChar(buffer, index);
00440                         index += parseButtons(buffer, index);
00441                         index += parseDistance(buffer, index);
00442                         index += parseAngle(buffer, index);
00443                         index += parseChargingState(buffer, index);
00444                         index += parseVoltage(buffer, index);
00445                         index += parseCurrent(buffer, index);
00446                         index += parseTemperature(buffer, index);
00447                         index += parseBatteryCharge(buffer, index);
00448                         index += parseBatteryCapacity(buffer, index);
00449                         index += parseWallSignal(buffer, index);
00450                         index += parseLeftCliffSignal(buffer, index);
00451                         index += parseFrontLeftCliffSignal(buffer, index);
00452                         index += parseFontRightCliffSignal(buffer, index);
00453                         index += parseRightCliffSignal(buffer, index);
00454                         index += 3;     // Unused bytes
00455                         index += parseChargingSource(buffer, index);
00456                         index += parseOiMode(buffer, index);
00457                         index += parseSongNumber(buffer, index);
00458                         index += parseSongPlaying(buffer, index);
00459                         index += parseNumberOfStreamPackets(buffer, index);
00460                         index += parseRequestedVelocity(buffer, index);
00461                         index += parseRequestedRadius(buffer, index);
00462                         index += parseRequestedRightVelocity(buffer, index);
00463                         index += parseRequestedLeftVelocity(buffer, index);
00464                         i++;
00465                 }
00466                 if(sensor_packets_[i]==OI_PACKET_BUMPS_DROPS)
00467                 {
00468                         index += parseBumpersAndWheeldrops(buffer, index);
00469                         i++;
00470                 }
00471                 if(sensor_packets_[i]==OI_PACKET_WALL)
00472                 {
00473                         index += parseWall(buffer, index);
00474                         i++;
00475                 }
00476                 if(sensor_packets_[i]==OI_PACKET_CLIFF_LEFT)
00477                 {
00478                         index += parseLeftCliff(buffer, index);
00479                         i++;
00480                 }
00481                 if(sensor_packets_[i]==OI_PACKET_CLIFF_FRONT_LEFT)
00482                 {
00483                         index += parseFrontLeftCliff(buffer, index);
00484                         i++;
00485                 }
00486                 if(sensor_packets_[i]==OI_PACKET_CLIFF_FRONT_RIGHT)
00487                 {
00488                         index += parseFrontRightCliff(buffer, index);
00489                         i++;
00490                 }
00491                 if(sensor_packets_[i]==OI_PACKET_CLIFF_RIGHT)
00492                 {
00493                         index += parseRightCliff(buffer, index);
00494                         i++;
00495                 }
00496                 if(sensor_packets_[i]==OI_PACKET_VIRTUAL_WALL)
00497                 {
00498                         index += parseVirtualWall(buffer, index);
00499                         i++;
00500                 }
00501                 if(sensor_packets_[i]==OI_PACKET_WHEEL_OVERCURRENTS)
00502                 {
00503                         index += parseOvercurrents(buffer, index);
00504                         i++;
00505                 }
00506                 if(sensor_packets_[i]==OI_PACKET_DIRT_DETECT)
00507                 {
00508                         index += parseDirtDetector(buffer, index);
00509                         i++;
00510                 }
00511                 if(sensor_packets_[i]==OI_PACKET_IR_CHAR_OMNI)
00512                 {
00513                         index += parseIrOmniChar(buffer, index);
00514                         i++;
00515                 }
00516                 if(sensor_packets_[i]==OI_PACKET_BUTTONS)
00517                 {
00518                         index += parseButtons(buffer, index);
00519                         i++;
00520                 }
00521                 if(sensor_packets_[i]==OI_PACKET_DISTANCE)
00522                 {
00523                         index += parseDistance(buffer, index);
00524                         i++;
00525                 }
00526                 if(sensor_packets_[i]==OI_PACKET_ANGLE)
00527                 {
00528                         index += parseAngle(buffer, index);
00529                         i++;
00530                 }
00531                 if(sensor_packets_[i]==OI_PACKET_CHARGING_STATE)
00532                 {
00533                         index += parseChargingState(buffer, index);
00534                         i++;
00535                 }
00536                 if(sensor_packets_[i]==OI_PACKET_VOLTAGE)
00537                 {
00538                         index += parseVoltage(buffer, index);
00539                         i++;
00540                 }
00541                 if(sensor_packets_[i]==OI_PACKET_CURRENT)
00542                 {
00543                         index += parseCurrent(buffer, index);
00544                         i++;
00545                 }
00546                 if(sensor_packets_[i]==OI_PACKET_TEMPERATURE)
00547                 {
00548                         index += parseTemperature(buffer, index);
00549                         i++;
00550                 }
00551                 if(sensor_packets_[i]==OI_PACKET_BATTERY_CHARGE)
00552                 {
00553                         index += parseBatteryCharge(buffer, index);
00554                         i++;
00555                 }
00556                 if(sensor_packets_[i]==OI_PACKET_BATTERY_CAPACITY)
00557                 {
00558                         index += parseBatteryCapacity(buffer, index);
00559                         i++;
00560                 }
00561                 if(sensor_packets_[i]==OI_PACKET_WALL_SIGNAL)
00562                 {
00563                         index += parseWallSignal(buffer, index);
00564                         i++;
00565                 }
00566                 if(sensor_packets_[i]==OI_PACKET_CLIFF_LEFT_SIGNAL)
00567                 {
00568                         index += parseLeftCliffSignal(buffer, index);
00569                         i++;
00570                 }
00571                 if(sensor_packets_[i]==OI_PACKET_CLIFF_FRONT_LEFT_SIGNAL)
00572                 {
00573                         index += parseFrontLeftCliffSignal(buffer, index);
00574                         i++;
00575                 }
00576                 if(sensor_packets_[i]==OI_PACKET_CLIFF_FRONT_RIGHT_SIGNAL)
00577                 {
00578                         index += parseFontRightCliffSignal(buffer, index);
00579                         i++;
00580                 }
00581                 if(sensor_packets_[i]==OI_PACKET_CLIFF_RIGHT_SIGNAL)
00582                 {
00583                         index += parseRightCliffSignal(buffer, index);
00584                         i++;
00585                 }
00586                 if(sensor_packets_[i]==OI_PACKET_CHARGE_SOURCES)
00587                 {
00588                         index += parseChargingSource(buffer, index);
00589                         i++;
00590                 }
00591                 if(sensor_packets_[i]==OI_PACKET_OI_MODE)
00592                 {
00593                         index += parseOiMode(buffer, index);
00594                         i++;
00595                 }
00596                 if(sensor_packets_[i]==OI_PACKET_SONG_NUMBER)
00597                 {
00598                         index += parseSongNumber(buffer, index);
00599                         i++;
00600                 }
00601                 if(sensor_packets_[i]==OI_PACKET_SONG_PLAYING)
00602                 {
00603                         index += parseSongPlaying(buffer, index);
00604                         i++;
00605                 }
00606                 if(sensor_packets_[i]==OI_PACKET_STREAM_PACKETS)
00607                 {
00608                         index += parseNumberOfStreamPackets(buffer, index);
00609                         i++;
00610                 }
00611                 if(sensor_packets_[i]==OI_PACKET_REQ_VELOCITY)
00612                 {
00613                         index += parseRequestedVelocity(buffer, index);
00614                         i++;
00615                 }
00616                 if(sensor_packets_[i]==OI_PACKET_REQ_RADIUS)
00617                 {
00618                         index += parseRequestedRadius(buffer, index);
00619                         i++;
00620                 }
00621                 if(sensor_packets_[i]==OI_PACKET_REQ_RIGHT_VELOCITY)
00622                 {
00623                         index += parseRequestedRightVelocity(buffer, index);
00624                         i++;
00625                 }
00626                 if(sensor_packets_[i]==OI_PACKET_REQ_LEFT_VELOCITY)
00627                 {
00628                         index += parseRequestedLeftVelocity(buffer, index);
00629                         i++;
00630                 }
00631                 if(sensor_packets_[i]==OI_PACKET_RIGHT_ENCODER)
00632                 {
00633                         index += parseRightEncoderCounts(buffer, index);
00634                         i++;
00635                 }
00636                 if(sensor_packets_[i]==OI_PACKET_LEFT_ENCODER)
00637                 {
00638                         index += parseLeftEncoderCounts(buffer, index);
00639                         i++;
00640                 }
00641                 if(sensor_packets_[i]==OI_PACKET_LIGHT_BUMPER)
00642                 {
00643                         index += parseLightBumper(buffer, index);
00644                         i++;
00645                 }
00646                 if(sensor_packets_[i]==OI_PACKET_LIGHT_BUMPER_LEFT)
00647                 {
00648                         index += parseLightBumperLeftSignal(buffer, index);
00649                         i++;
00650                 }
00651                 if(sensor_packets_[i]==OI_PACKET_LIGHT_BUMPER_FRONT_LEFT)
00652                 {
00653                         index += parseLightBumperFrontLeftSignal(buffer, index);
00654                         i++;
00655                 }
00656                 if(sensor_packets_[i]==OI_PACKET_LIGHT_BUMPER_CENTER_LEFT)
00657                 {
00658                         index += parseLightBumperCenterLeftSignal(buffer, index);
00659                         i++;
00660                 }
00661                 if(sensor_packets_[i]==OI_PACKET_LIGHT_BUMPER_CENTER_RIGHT)
00662                 {
00663                         index += parseLightBumperCenterRightSignal(buffer, index);
00664                         i++;
00665                 }
00666                 if(sensor_packets_[i]==OI_PACKET_LIGHT_BUMPER_FRONT_RIGHT)
00667                 {
00668                         index += parseLightBumperFrontRightSignal(buffer, index);
00669                         i++;
00670                 }
00671                 if(sensor_packets_[i]==OI_PACKET_LIGHT_BUMPER_RIGHT)
00672                 {
00673                         index += parseLightBumperRightSignal(buffer, index);
00674                         i++;
00675                 }
00676                 if(sensor_packets_[i]==OI_PACKET_IR_CHAR_LEFT)
00677                 {
00678                         index += parseIrCharLeft(buffer, index);
00679                         i++;
00680                 }
00681                 if(sensor_packets_[i]==OI_PACKET_IR_CHAR_RIGHT)
00682                 {
00683                         index += parseIrCharRight(buffer, index);
00684                         i++;
00685                 }
00686                 if(sensor_packets_[i]==OI_PACKET_LEFT_MOTOR_CURRENT)
00687                 {
00688                         index += parseLeftMotorCurrent(buffer, index);
00689                         i++;
00690                 }
00691                 if(sensor_packets_[i]==OI_PACKET_RIGHT_MOTOR_CURRENT)
00692                 {
00693                         index += parseRightMotorCurrent(buffer, index);
00694                         i++;
00695                 }
00696                 if(sensor_packets_[i]==OI_PACKET_BRUSH_MOTOR_CURRENT)
00697                 {
00698                         index += parseMainBrushMotorCurrent(buffer, index);
00699                         i++;
00700                 }
00701                 if(sensor_packets_[i]==OI_PACKET_SIDE_BRUSH_MOTOR_CURRENT)
00702                 {
00703                         index += parseSideBrushMotorCurrent(buffer, index);
00704                         i++;
00705                 }
00706                 if(sensor_packets_[i]==OI_PACKET_STASIS)
00707                 {
00708                         index += parseStasis(buffer, index);
00709                         i++;
00710                 }
00711                 if(sensor_packets_[i]==OI_PACKET_GROUP_100)     // PACKETS 7-58
00712                 {
00713                         index += parseBumpersAndWheeldrops(buffer, index);
00714                         index += parseWall(buffer, index);
00715                         index += parseLeftCliff(buffer, index);
00716                         index += parseFrontLeftCliff(buffer, index);
00717                         index += parseFrontRightCliff(buffer, index);
00718                         index += parseRightCliff(buffer, index);
00719                         index += parseVirtualWall(buffer, index);
00720                         index += parseOvercurrents(buffer, index);
00721                         index += parseDirtDetector(buffer, index);
00722                         index ++;       // Unused byte
00723                         index += parseIrOmniChar(buffer, index);
00724                         index += parseButtons(buffer, index);
00725                         index += parseDistance(buffer, index);
00726                         index += parseAngle(buffer, index);
00727                         index += parseChargingState(buffer, index);
00728                         index += parseVoltage(buffer, index);
00729                         index += parseCurrent(buffer, index);
00730                         index += parseTemperature(buffer, index);
00731                         index += parseBatteryCharge(buffer, index);
00732                         index += parseBatteryCapacity(buffer, index);
00733                         index += parseWallSignal(buffer, index);
00734                         index += parseLeftCliffSignal(buffer, index);
00735                         index += parseFrontLeftCliffSignal(buffer, index);
00736                         index += parseFontRightCliffSignal(buffer, index);
00737                         index += parseRightCliffSignal(buffer, index);
00738                         index += 3;     // Unused bytes
00739                         index += parseChargingSource(buffer, index);
00740                         index += parseOiMode(buffer, index);
00741                         index += parseSongNumber(buffer, index);
00742                         index += parseSongPlaying(buffer, index);
00743                         index += parseNumberOfStreamPackets(buffer, index);
00744                         index += parseRequestedVelocity(buffer, index);
00745                         index += parseRequestedRadius(buffer, index);
00746                         index += parseRequestedRightVelocity(buffer, index);
00747                         index += parseRequestedLeftVelocity(buffer, index);
00748                         index += parseRightEncoderCounts(buffer, index);
00749                         index += parseLeftEncoderCounts(buffer, index);
00750                         index += parseLightBumper(buffer, index);
00751                         index += parseLightBumperLeftSignal(buffer, index);
00752                         index += parseLightBumperFrontLeftSignal(buffer, index);
00753                         index += parseLightBumperCenterLeftSignal(buffer, index);
00754                         index += parseLightBumperCenterRightSignal(buffer, index);
00755                         index += parseLightBumperFrontRightSignal(buffer, index);
00756                         index += parseLightBumperRightSignal(buffer, index);
00757                         index += parseIrCharLeft(buffer, index);
00758                         index += parseIrCharRight(buffer, index);
00759                         index += parseLeftMotorCurrent(buffer, index);
00760                         index += parseRightMotorCurrent(buffer, index);
00761                         index += parseMainBrushMotorCurrent(buffer, index);
00762                         index += parseSideBrushMotorCurrent(buffer, index);
00763                         index += parseStasis(buffer, index);
00764                         i++;   
00765                 }
00766                 if(sensor_packets_[i]==OI_PACKET_GROUP_101)     // PACKETS 43-58
00767                 {
00768                         index += parseRightEncoderCounts(buffer, index);
00769                         index += parseLeftEncoderCounts(buffer, index);
00770                         index += parseLightBumper(buffer, index);
00771                         index += parseLightBumperLeftSignal(buffer, index);
00772                         index += parseLightBumperFrontLeftSignal(buffer, index);
00773                         index += parseLightBumperCenterLeftSignal(buffer, index);
00774                         index += parseLightBumperCenterRightSignal(buffer, index);
00775                         index += parseLightBumperFrontRightSignal(buffer, index);
00776                         index += parseLightBumperRightSignal(buffer, index);
00777                         index += parseIrCharLeft(buffer, index);
00778                         index += parseIrCharRight(buffer, index);
00779                         index += parseLeftMotorCurrent(buffer, index);
00780                         index += parseRightMotorCurrent(buffer, index);
00781                         index += parseMainBrushMotorCurrent(buffer, index);
00782                         index += parseSideBrushMotorCurrent(buffer, index);
00783                         index += parseStasis(buffer, index);
00784                         i++;
00785                 }
00786                 if(sensor_packets_[i]==OI_PACKET_GROUP_106)     // PACKETS 46-51
00787                 {
00788                         index += parseLightBumperLeftSignal(buffer, index);
00789                         index += parseLightBumperFrontLeftSignal(buffer, index);
00790                         index += parseLightBumperCenterLeftSignal(buffer, index);
00791                         index += parseLightBumperCenterRightSignal(buffer, index);
00792                         index += parseLightBumperFrontRightSignal(buffer, index);
00793                         index += parseLightBumperRightSignal(buffer, index);
00794                         i++;
00795                 }
00796                 if(sensor_packets_[i]==OI_PACKET_GROUP_107)     // PACKETS 54-58
00797                 {
00798                         index += parseLeftMotorCurrent(buffer, index);
00799                         index += parseRightMotorCurrent(buffer, index);
00800                         index += parseMainBrushMotorCurrent(buffer, index);
00801                         index += parseSideBrushMotorCurrent(buffer, index);
00802                         index += parseStasis(buffer, index);
00803                         i++;
00804                 }
00805         }
00806         return(0);
00807 }
00808 
00809 int irobot::OpenInterface::parseBumpersAndWheeldrops(unsigned char * buffer, int index)
00810 {
00811         // Bumps, wheeldrops    
00812         this->bumper_[RIGHT] = (buffer[index]) & 0x01;
00813         this->bumper_[LEFT] = (buffer[index] >> 1) & 0x01;
00814         this->wheel_drop_[RIGHT] = (buffer[index] >> 2) & 0x01;
00815         this->wheel_drop_[LEFT] = (buffer[index] >> 3) & 0x01;
00816         
00817         return OI_PACKET_BUMPS_DROPS_SIZE;
00818 }
00819 
00820 int irobot::OpenInterface::parseWall(unsigned char * buffer, int index)
00821 {
00822         // Wall
00823         this->wall_ = buffer[index] & 0x01;
00824         
00825         return OI_PACKET_WALL_SIZE;
00826 }
00827         
00828 int irobot::OpenInterface::parseLeftCliff(unsigned char * buffer, int index)
00829 {
00830         // Cliffs
00831         this->cliff_[LEFT] = buffer[index] & 0x01;
00832         
00833         return OI_PACKET_CLIFF_LEFT_SIZE;
00834 }
00835 
00836 int irobot::OpenInterface::parseFrontLeftCliff(unsigned char * buffer, int index)
00837 {
00838         // Cliffs
00839         this->cliff_[FRONT_LEFT] = buffer[index] & 0x01;
00840         
00841         return OI_PACKET_CLIFF_FRONT_LEFT_SIZE;
00842 }
00843 
00844 int irobot::OpenInterface::parseFrontRightCliff(unsigned char * buffer, int index)
00845 {
00846         // Cliffs
00847         this->cliff_[FRONT_RIGHT] = buffer[index] & 0x01;
00848         
00849         return OI_PACKET_CLIFF_FRONT_RIGHT_SIZE;
00850 }
00851 
00852 int irobot::OpenInterface::parseRightCliff(unsigned char * buffer, int index)
00853 {
00854         // Cliffs
00855         this->cliff_[RIGHT] = buffer[index] & 0x01;
00856         
00857         return OI_PACKET_CLIFF_RIGHT_SIZE;
00858 }
00859 
00860 int irobot::OpenInterface::parseVirtualWall(unsigned char * buffer, int index)
00861 {
00862         // Virtual Wall
00863         this->virtual_wall_ = buffer[index] & 0x01;
00864         
00865         return OI_PACKET_VIRTUAL_WALL_SIZE;
00866 }
00867         
00868 int irobot::OpenInterface::parseOvercurrents(unsigned char * buffer, int index)
00869 {
00870         // Overcurrent
00871         unsigned char byte = buffer[index];
00872         
00873         this->overcurrent_[SIDE_BRUSH] = (byte >> 0) & 0x01;
00874         this->overcurrent_[MAIN_BRUSH] = (byte >> 2) & 0x01;
00875         this->overcurrent_[RIGHT] = (byte >> 3) & 0x01;
00876         this->overcurrent_[LEFT] = (byte >> 4) & 0x01;
00877         
00878         return OI_PACKET_WHEEL_OVERCURRENTS_SIZE;
00879 }
00880 
00881 int irobot::OpenInterface::parseDirtDetector(unsigned char * buffer, int index)
00882 {
00883         // Dirt Detector
00884         this->dirt_detect_ = buffer[index];
00885 
00886         return OI_PACKET_DIRT_DETECT_SIZE;
00887 }
00888         
00889 int irobot::OpenInterface::parseIrOmniChar(unsigned char * buffer, int index)
00890 {
00891         // Infrared Character Omni
00892         this->ir_char_[OMNI] = buffer[index];
00893 
00894         return OI_PACKET_IR_CHAR_OMNI_SIZE;
00895 }
00896 
00897 int irobot::OpenInterface::parseButtons(unsigned char * buffer, int index)
00898 {
00899         // Buttons
00900         for(int i=0 ; i<8 ; i++) this->buttons_[i] = (buffer[index] >> i) & 0x01;
00901         
00902         return OI_PACKET_BUTTONS_SIZE;
00903 }
00904         
00905 int irobot::OpenInterface::parseDistance(unsigned char * buffer, int index)
00906 {
00907         // Distance
00908         this->distance_ = buffer2signed_int(buffer, index);
00909         
00910         return OI_PACKET_DISTANCE_SIZE;
00911 }
00912 
00913 int irobot::OpenInterface::parseAngle(unsigned char * buffer, int index)
00914 {
00915         // Angle
00916         this->angle_ = buffer2signed_int(buffer, index);
00917 
00918         return OI_PACKET_ANGLE_SIZE;
00919 }
00920         
00921 int irobot::OpenInterface::parseChargingState(unsigned char * buffer, int index)
00922 {
00923         // Charging State
00924         unsigned char byte = buffer[index];
00925         
00926         this->power_cord_ = (byte >> 0) & 0x01;
00927         this->dock_ = (byte >> 1) & 0x01;
00928 
00929         return OI_PACKET_CHARGING_STATE_SIZE;
00930 }
00931 
00932 int irobot::OpenInterface::parseVoltage(unsigned char * buffer, int index)
00933 {
00934         // Voltage
00935         this->voltage_ = (float)(buffer2unsigned_int(buffer, index) / 1000.0);
00936 
00937         return OI_PACKET_VOLTAGE_SIZE;
00938 }
00939 
00940 int irobot::OpenInterface::parseCurrent(unsigned char * buffer, int index)
00941 {
00942         // Current
00943         this->current_ = (float)(buffer2signed_int(buffer, index) / 1000.0);
00944 
00945         return OI_PACKET_CURRENT_SIZE;
00946 }
00947 
00948 int irobot::OpenInterface::parseTemperature(unsigned char * buffer, int index)
00949 {
00950         // Temperature
00951         this->temperature_ = (char)(buffer[index]);
00952 
00953         return OI_PACKET_TEMPERATURE_SIZE;
00954 }
00955 
00956 int irobot::OpenInterface::parseBatteryCharge(unsigned char * buffer, int index)
00957 {
00958         // Charge
00959         this->charge_ = (float)(buffer2unsigned_int(buffer, index) / 1000.0);
00960 
00961         return OI_PACKET_BATTERY_CHARGE_SIZE;
00962 }
00963 
00964 int irobot::OpenInterface::parseBatteryCapacity(unsigned char * buffer, int index)
00965 {
00966         // Capacity
00967         this->capacity_ = (float)(buffer2unsigned_int(buffer, index) / 1000.0);
00968 
00969         return OI_PACKET_BATTERY_CAPACITY_SIZE;
00970 }
00971         
00972 int irobot::OpenInterface::parseWallSignal(unsigned char * buffer, int index)
00973 {
00974         // Wall signal
00975         this->wall_signal_ = buffer2unsigned_int(buffer, index);
00976         
00977         return OI_PACKET_WALL_SIGNAL_SIZE;
00978 }
00979         
00980 int irobot::OpenInterface::parseLeftCliffSignal(unsigned char * buffer, int index)
00981 {
00982         // Cliff signals
00983         this->cliff_signal_[LEFT] = buffer2unsigned_int(buffer, index);
00984         
00985         return OI_PACKET_CLIFF_LEFT_SIGNAL_SIZE;
00986 }
00987 
00988 int irobot::OpenInterface::parseFrontLeftCliffSignal(unsigned char * buffer, int index)
00989 {
00990         // Cliff signals
00991         this->cliff_signal_[FRONT_LEFT] = buffer2unsigned_int(buffer, index);
00992         
00993         return OI_PACKET_CLIFF_FRONT_LEFT_SIGNAL_SIZE;
00994 }
00995         
00996 int irobot::OpenInterface::parseFontRightCliffSignal(unsigned char * buffer, int index)
00997 {
00998         // Cliff signals
00999         this->cliff_signal_[FRONT_RIGHT] = buffer2unsigned_int(buffer, index);
01000         
01001         return OI_PACKET_CLIFF_FRONT_RIGHT_SIGNAL_SIZE;
01002 }
01003 
01004 int irobot::OpenInterface::parseRightCliffSignal(unsigned char * buffer, int index)
01005 {
01006         // Cliff signals
01007         this->cliff_signal_[RIGHT] = buffer2unsigned_int(buffer, index);
01008         
01009         return OI_PACKET_CLIFF_RIGHT_SIGNAL_SIZE;
01010 }       
01011         
01012 int irobot::OpenInterface::parseChargingSource(unsigned char * buffer, int index)
01013 {
01014         // Charging soruces available
01015         this->power_cord_ = (buffer[index] >> 0) & 0x01;
01016         this->dock_ = (buffer[index] >> 1) & 0x01;
01017 
01018         return OI_PACKET_CHARGE_SOURCES_SIZE;
01019 }
01020 
01021 int irobot::OpenInterface::parseOiMode(unsigned char * buffer, int index)
01022 {
01023         this->OImode_ = buffer[index];
01024 
01025         return OI_PACKET_OI_MODE_SIZE;
01026 }
01027 
01028 int irobot::OpenInterface::parseSongNumber(unsigned char * buffer, int index)
01029 {
01030         // TODO
01031         return OI_PACKET_SONG_NUMBER_SIZE;
01032 }
01033 
01034 int irobot::OpenInterface::parseSongPlaying(unsigned char * buffer, int index)
01035 {
01036         // TODO
01037         return OI_PACKET_SONG_PLAYING_SIZE;
01038 }
01039 
01040 int irobot::OpenInterface::parseNumberOfStreamPackets(unsigned char * buffer, int index)
01041 {
01042         // TODO
01043         return OI_PACKET_STREAM_PACKETS_SIZE;
01044 }
01045 
01046 int irobot::OpenInterface::parseRequestedVelocity(unsigned char * buffer, int index)
01047 {
01048         // TODO
01049         return OI_PACKET_REQ_VELOCITY_SIZE;
01050 }
01051 
01052 int irobot::OpenInterface::parseRequestedRadius(unsigned char * buffer, int index)
01053 {
01054         // TODO
01055         return OI_PACKET_REQ_RADIUS_SIZE;
01056 }
01057 
01058 int irobot::OpenInterface::parseRequestedRightVelocity(unsigned char * buffer, int index)
01059 {
01060         // TODO
01061         return OI_PACKET_REQ_RIGHT_VELOCITY_SIZE;
01062 }
01063 
01064 int irobot::OpenInterface::parseRequestedLeftVelocity(unsigned char * buffer, int index)
01065 {
01066         // TODO
01067         return OI_PACKET_REQ_LEFT_VELOCITY_SIZE;
01068 }
01069 
01070 int irobot::OpenInterface::parseRightEncoderCounts(unsigned char * buffer, int index)
01071 {
01072         // Right encoder counts
01073         uint16_t right_encoder_counts = buffer2unsigned_int(buffer, index);
01074 
01075         //printf("Right Encoder: %d\n", rightEncoderCounts);
01076 
01077         if(encoder_counts_[RIGHT] == -1 || right_encoder_counts == last_encoder_counts_[RIGHT]) // First time, we need 2 to make it work!
01078         {
01079                 encoder_counts_[RIGHT] = 0;
01080         }
01081         else
01082         {
01083                 encoder_counts_[RIGHT] = (int)(right_encoder_counts - last_encoder_counts_[RIGHT]);
01084                 
01085                 if(encoder_counts_[RIGHT] > ROOMBA_MAX_ENCODER_COUNTS/10) encoder_counts_[RIGHT] = encoder_counts_[RIGHT] - ROOMBA_MAX_ENCODER_COUNTS;
01086                 if(encoder_counts_[RIGHT] < -ROOMBA_MAX_ENCODER_COUNTS/10) encoder_counts_[RIGHT] = ROOMBA_MAX_ENCODER_COUNTS + encoder_counts_[RIGHT];
01087         }
01088         last_encoder_counts_[RIGHT] = right_encoder_counts;
01089         
01090         return OI_PACKET_RIGHT_ENCODER_SIZE;
01091 }
01092 
01093 int irobot::OpenInterface::parseLeftEncoderCounts(unsigned char * buffer, int index)
01094 {
01095         // Left encoder counts
01096         uint16_t left_encoder_counts = buffer2unsigned_int(buffer, index);
01097 
01098         //printf("Left Encoder: %d\n", leftEncoderCounts);
01099 
01100         if(encoder_counts_[LEFT] == -1 || left_encoder_counts == last_encoder_counts_[LEFT])    // First time, we need 2 to make it work!
01101         {
01102                 encoder_counts_[LEFT] = 0;
01103         }
01104         else
01105         {
01106                 encoder_counts_[LEFT] = (int)(left_encoder_counts - last_encoder_counts_[LEFT]);
01107                 
01108                 if(encoder_counts_[LEFT] > ROOMBA_MAX_ENCODER_COUNTS/10) encoder_counts_[LEFT] = encoder_counts_[LEFT] - ROOMBA_MAX_ENCODER_COUNTS;
01109                 if(encoder_counts_[LEFT] < -ROOMBA_MAX_ENCODER_COUNTS/10) encoder_counts_[LEFT] = ROOMBA_MAX_ENCODER_COUNTS + encoder_counts_[LEFT];
01110         }
01111         last_encoder_counts_[LEFT] = left_encoder_counts;
01112         
01113         return OI_PACKET_LEFT_ENCODER_SIZE;
01114 }
01115         
01116 int irobot::OpenInterface::parseLightBumper(unsigned char * buffer, int index)
01117 {
01118         // Light bumper
01119         this->ir_bumper_[LEFT] = (buffer[index]) & 0x01;
01120         this->ir_bumper_[FRONT_LEFT] = (buffer[index] >> 1) & 0x01;
01121         this->ir_bumper_[CENTER_LEFT] = (buffer[index] >> 2) & 0x01;
01122         this->ir_bumper_[CENTER_RIGHT] = (buffer[index] >> 3) & 0x01;
01123         this->ir_bumper_[FRONT_RIGHT] = (buffer[index] >> 4) & 0x01;
01124         this->ir_bumper_[RIGHT] = (buffer[index] >> 5) & 0x01;
01125         
01126         return OI_PACKET_LIGHT_BUMPER_SIZE;
01127 }
01128 
01129 int irobot::OpenInterface::parseLightBumperLeftSignal(unsigned char * buffer, int index)
01130 {
01131         // Light bumper signal
01132         this->ir_bumper_signal_[LEFT] = buffer2unsigned_int(buffer, index);
01133         
01134         return OI_PACKET_LIGHT_BUMPER_LEFT_SIZE;
01135 }
01136 
01137 int irobot::OpenInterface::parseLightBumperFrontLeftSignal(unsigned char * buffer, int index)
01138 {
01139         // Light bumper signal
01140         this->ir_bumper_signal_[FRONT_LEFT] = buffer2unsigned_int(buffer, index);
01141         
01142         return OI_PACKET_LIGHT_BUMPER_FRONT_LEFT_SIZE;
01143 }
01144 
01145 int irobot::OpenInterface::parseLightBumperCenterLeftSignal(unsigned char * buffer, int index)
01146 {
01147         // Light bumper signal
01148         this->ir_bumper_signal_[CENTER_LEFT] = buffer2unsigned_int(buffer, index);
01149         
01150         return OI_PACKET_LIGHT_BUMPER_CENTER_LEFT_SIZE;
01151 }
01152 
01153 int irobot::OpenInterface::parseLightBumperCenterRightSignal(unsigned char * buffer, int index)
01154 {
01155         // Light bumper signal
01156         this->ir_bumper_signal_[CENTER_RIGHT] = buffer2unsigned_int(buffer, index);
01157         
01158         return OI_PACKET_LIGHT_BUMPER_CENTER_RIGHT_SIZE;
01159 }
01160 
01161 int irobot::OpenInterface::parseLightBumperFrontRightSignal(unsigned char * buffer, int index)
01162 {
01163         // Light bumper signal
01164         this->ir_bumper_signal_[FRONT_RIGHT] = buffer2unsigned_int(buffer, index);
01165         
01166         return OI_PACKET_LIGHT_BUMPER_FRONT_RIGHT_SIZE;
01167 }
01168         
01169 int irobot::OpenInterface::parseLightBumperRightSignal(unsigned char * buffer, int index)
01170 {
01171         // Light bumper signal
01172         this->ir_bumper_signal_[RIGHT] = buffer2unsigned_int(buffer, index);
01173         
01174         return OI_PACKET_LIGHT_BUMPER_RIGHT_SIZE;
01175 }
01176 
01177 int irobot::OpenInterface::parseIrCharLeft(unsigned char * buffer, int index)
01178 {
01179         // Infrared character left
01180         this->ir_char_[LEFT] = buffer[index];
01181 
01182         return OI_PACKET_IR_CHAR_LEFT_SIZE;
01183 }
01184         
01185 int irobot::OpenInterface::parseIrCharRight(unsigned char * buffer, int index)
01186 {
01187         // Infrared character left
01188         this->ir_char_[RIGHT] = buffer[index];
01189         
01190         return OI_PACKET_IR_CHAR_RIGHT_SIZE;
01191 }
01192         
01193 int irobot::OpenInterface::parseLeftMotorCurrent(unsigned char * buffer, int index)
01194 {
01195         // Left motor current
01196         this->motor_current_[LEFT] = buffer2signed_int(buffer, index);
01197         
01198         return OI_PACKET_LEFT_MOTOR_CURRENT_SIZE;
01199 }
01200 
01201 int irobot::OpenInterface::parseRightMotorCurrent(unsigned char * buffer, int index)
01202 {
01203         // Left motor current
01204         this->motor_current_[RIGHT] = buffer2signed_int(buffer, index);
01205         
01206         return OI_PACKET_RIGHT_MOTOR_CURRENT_SIZE;
01207 }
01208 
01209 int irobot::OpenInterface::parseMainBrushMotorCurrent(unsigned char * buffer, int index)
01210 {
01211         // Main brush motor current
01212         this->motor_current_[MAIN_BRUSH] = buffer2signed_int(buffer, index);
01213         
01214         return OI_PACKET_BRUSH_MOTOR_CURRENT_SIZE;
01215 }
01216 
01217 int irobot::OpenInterface::parseSideBrushMotorCurrent(unsigned char * buffer, int index)
01218 {
01219         // Main brush motor current
01220         this->motor_current_[SIDE_BRUSH] = buffer2signed_int(buffer, index);
01221         
01222         return OI_PACKET_SIDE_BRUSH_MOTOR_CURRENT_SIZE;
01223 }
01224 
01225 int irobot::OpenInterface::parseStasis(unsigned char * buffer, int index)
01226 {
01227         // Stasis
01228         this->stasis_ = (buffer[index] >> 0) & 0x01;
01229 
01230         return OI_PACKET_STASIS_SIZE;
01231 }
01232 
01233 int irobot::OpenInterface::buffer2signed_int(unsigned char * buffer, int index)
01234 {
01235         int16_t signed_int;
01236         
01237         memcpy(&signed_int, buffer+index, 2);
01238         signed_int = ntohs(signed_int);
01239         
01240         return (int)signed_int;
01241 }
01242 
01243 int irobot::OpenInterface::buffer2unsigned_int(unsigned char * buffer, int index)
01244 {
01245         uint16_t unsigned_int;
01246 
01247         memcpy(&unsigned_int, buffer+index, 2);
01248         unsigned_int = ntohs(unsigned_int);
01249         
01250         return (int)unsigned_int;
01251 }
01252 
01253 
01254 // *****************************************************************************
01255 // Calculate Roomba odometry
01256 void irobot::OpenInterface::calculateOdometry()
01257 {       
01258         double dist = (encoder_counts_[RIGHT]*ROOMBA_PULSES_TO_M + encoder_counts_[LEFT]*ROOMBA_PULSES_TO_M) / 2.0; 
01259         double ang = (encoder_counts_[RIGHT]*ROOMBA_PULSES_TO_M - encoder_counts_[LEFT]*ROOMBA_PULSES_TO_M) / -ROOMBA_AXLE_LENGTH;
01260 
01261         // Update odometry
01262         this->odometry_yaw_ = NORMALIZE(this->odometry_yaw_ + ang);                     // rad
01263         this->odometry_x_ = this->odometry_x_ + dist*cos(odometry_yaw_);                // m
01264         this->odometry_y_ = this->odometry_y_ + dist*sin(odometry_yaw_);                // m
01265 }
01266 
01267 
01268 // *****************************************************************************
01269 // Reset Roomba odometry
01270 void irobot::OpenInterface::resetOdometry()
01271 {
01272         this->setOdometry(0.0, 0.0, 0.0);
01273 }
01274 
01275 
01276 // *****************************************************************************
01277 // Set Roomba odometry
01278 void irobot::OpenInterface::setOdometry(double new_x, double new_y, double new_yaw)
01279 {
01280         this->odometry_x_ = new_x;
01281         this->odometry_y_ = new_y;
01282         this->odometry_yaw_ = new_yaw;
01283 }
01284 
01285 
01286 // *****************************************************************************
01287 // Clean
01288 int irobot::OpenInterface::clean()
01289 {
01290         return sendOpcode(OI_OPCODE_CLEAN);
01291 }
01292 
01293 
01294 // *****************************************************************************
01295 // Max
01296 int irobot::OpenInterface::max()
01297 {
01298         return sendOpcode(OI_OPCODE_MAX);
01299 }
01300 
01301 
01302 // *****************************************************************************
01303 // Spot
01304 int irobot::OpenInterface::spot()
01305 {
01306         return sendOpcode(OI_OPCODE_SPOT);
01307 }
01308 
01309 
01310 // *****************************************************************************
01311 // Go to the dock
01312 int irobot::OpenInterface::goDock()
01313 {
01314         return sendOpcode(OI_OPCODE_FORCE_DOCK);
01315 }
01316 
01317 
01318 // *****************************************************************************
01319 // Compose a song
01320 int irobot::OpenInterface::setSong(unsigned char song_number, unsigned char song_length, unsigned char *notes, unsigned char *note_lengths)
01321 {
01322         int size = 2*song_length+3;
01323         unsigned char cmd_buffer[size];
01324         unsigned char i;
01325         
01326         cmd_buffer[0] = (unsigned char)OI_OPCODE_SONG;
01327         cmd_buffer[1] = song_number;
01328         cmd_buffer[2] = song_length;
01329         
01330         for(i=0 ; i < song_length ; i++)
01331         {
01332                 cmd_buffer[3+(2*i)] = notes[i];
01333                 cmd_buffer[3+(2*i)+1] = note_lengths[i];
01334         }
01335         
01336         try{ serial_port_->write((char*)cmd_buffer, size); }
01337         catch(cereal::Exception& e){ return(-1); }
01338         return(0);
01339 }
01340 
01341 
01342 // *****************************************************************************
01343 // Play a song from the list
01344 int irobot::OpenInterface::playSong(unsigned char song_number)
01345 {
01346         unsigned char cmd_buffer[2];
01347         
01348         cmd_buffer[0] = (unsigned char)OI_OPCODE_PLAY;
01349         cmd_buffer[1] = song_number;
01350         
01351         try{ serial_port_->write((char*)cmd_buffer, 2); }
01352         catch(cereal::Exception& e){ return(-1); }
01353         return(0);
01354 }
01355 
01356 
01357 // *****************************************************************************
01358 // Set the LEDs
01359 int irobot::OpenInterface::setLeds(unsigned char check_robot, unsigned char dock, unsigned char spot, unsigned char debris, unsigned char power_color, unsigned char power_intensity)
01360 {
01361         unsigned char cmd_buffer[4];
01362         cmd_buffer[0] = (unsigned char)OI_OPCODE_LEDS;
01363         cmd_buffer[1] = debris | spot<<1 | dock<<2 | check_robot<<3;
01364         cmd_buffer[2] = power_color;
01365         cmd_buffer[3] = power_intensity;
01366         
01367         try{ serial_port_->write((char*)cmd_buffer, 4); }
01368         catch(cereal::Exception& e){ return(-1); }
01369         return(0);
01370 }
01371 
01372 
01373 // *****************************************************************************
01374 // Set the scheduling LEDs
01375 int irobot::OpenInterface::setSchedulingLeds(unsigned char sun, unsigned char mon, unsigned char tue, unsigned char wed, unsigned char thu, unsigned char fri, unsigned char sat, unsigned char colon, unsigned char pm, unsigned char am, unsigned char clock, unsigned char schedule)
01376 {
01377         unsigned char cmd_buffer[3];
01378         cmd_buffer[0] = OI_OPCODE_SCHEDULE_LEDS;
01379         cmd_buffer[1] = sun | mon<<1 | tue<<2 | wed<<3 | thu<<4 | fri<<5 | sat<<6;
01380         cmd_buffer[2] = colon | pm<<1 | am<<2 | clock<<3 | schedule<<4;
01381         
01382         try{ serial_port_->write((char*)cmd_buffer, 3); }
01383         catch(cereal::Exception& e){ return(-1); }
01384         return(0);
01385 }
01386 
01387 
01388 // *****************************************************************************
01389 // Set the digit LEDs
01390 int irobot::OpenInterface::setDigitLeds(unsigned char digit3, unsigned char digit2, unsigned char digit1, unsigned char digit0)
01391 {
01392         unsigned char cmd_buffer[5];
01393         cmd_buffer[0] = (unsigned char)OI_OPCODE_DIGIT_LEDS_ASCII;
01394         cmd_buffer[1] = digit3;
01395         cmd_buffer[2] = digit2;
01396         cmd_buffer[3] = digit1;
01397         cmd_buffer[4] = digit0;
01398         
01399         try{ serial_port_->write((char*)cmd_buffer, 5); }
01400         catch(cereal::Exception& e){ return(-1); }
01401         return(0);
01402 }
01403 
01404 
01405 // EOF


roomba_500_series
Author(s): Gonçalo Cabrita
autogenerated on Mon Jan 6 2014 11:26:40