BeoPilot.C

00001 #include "BeoPilot.H"
00002 #include "ros/ros.h"
00003 #include <control_toolbox/pid.h>
00004 #include <iostream>
00005 #include <stdio.h>
00006 #include <sys/types.h>
00007 #include <sys/stat.h>
00008 #include <dirent.h>
00009 #include <unistd.h>
00010 // ######################################################################
00011 BeoPilot::BeoPilot():
00012         itsSerial(new Serial()),
00013         itsRCChannels(7, -1),
00014         itsEmergencyMode(-1)
00015 {
00016         //Connect to the serial motor board
00017         //itsSerial->configureSearch ("motorboard", 115200);
00018         itsSerial->configure ("/dev/ttyUSB0", 115200);
00019         itsPidSpeed.initPid(0.4,0.0,0.0,2.5,0.0);
00020         itsPidRot.initPid(  1.0,0.5,0.02,2.5,0.0);
00021 }
00022 void BeoPilot::start()
00023 {
00024         itsSerial->start();
00025         usleep(1000);
00026         if(itsSerial->isSerialOk())
00027                 printf("[%s] found on [%s]\n", itsSerial->getDeviceDescriptor().c_str(), itsSerial->getDevName().c_str());
00028         itsPreviousTime = ros::Time::now();
00029         itsLastLeftEncoder = 0;
00030         itsLastRightEncoder = 0;
00031         itsRightEncoder = 0;
00032         itsLeftEncoder = 0;
00033 
00034         itsPidSpeed.reset();
00035         itsPidRot.reset();
00036 }
00037 
00038 // ######################################################################
00039 BeoPilot::~BeoPilot()
00040 {
00041         //Kill the motors on exit
00042         SetMotors(0,0);
00043 }
00044 void BeoPilot::UpdateRCStatus()
00045 {
00046         unsigned char cmd = 107;
00047         itsSerial->write(cmd);
00048         std::vector<unsigned char> frame = itsSerial->readFrame(cmd, 255);
00049         if(frame.size() == 26)
00050         {
00051                 itsRCChannels[0] = ((0x0FF & frame[ 0]) << 8) | ((0x0FF & frame[ 1]) << 0);
00052                 itsRCChannels[1] = ((0x0FF & frame[ 2]) << 8) | ((0x0FF & frame[ 3]) << 0);
00053                 itsRCChannels[2] = ((0x0FF & frame[ 4]) << 8) | ((0x0FF & frame[ 5]) << 0);
00054                 itsRCChannels[3] = ((0x0FF & frame[ 6]) << 8) | ((0x0FF & frame[ 7]) << 0);
00055                 itsRCChannels[4] = ((0x0FF & frame[ 8]) << 8) | ((0x0FF & frame[ 9]) << 0);
00056                 itsRCChannels[5] = ((0x0FF & frame[10]) << 8) | ((0x0FF & frame[11]) << 0);
00057                 itsRCChannels[6] = ((0x0FF & frame[12]) << 8) | ((0x0FF & frame[13]) << 0);
00058 
00059                 itsEmergencyMode = frame[14];
00060                 if(itsRCChannels[2] > 1800)
00061                         itsEmergencyMode = 255;
00062                 itsRemoteMode    = frame[15];
00063                 itsMotor1Speed   = (frame[16] - 64.0) / 64.0;
00064                 itsMotor2Speed   = (frame[17] - 64.0) / 64.0;
00065 
00066                 itsLastLeftEncoder  = itsLeftEncoder;
00067                 itsLastRightEncoder = itsRightEncoder;
00068                 itsLeftEncoder   = ((0x0FF & frame[18]) << 24) |
00069                                    ((0x0FF & frame[19]) << 16) |
00070                                    ((0x0FF & frame[20]) <<  8) |
00071                                    ((0x0FF & frame[21]) <<  0);
00072 
00073                 itsRightEncoder  = ((0x0FF & frame[22]) << 24) |
00074                                    ((0x0FF & frame[23]) << 16) |
00075                                    ((0x0FF & frame[24]) <<  8) |
00076                                    ((0x0FF & frame[25]) <<  0);
00077                 printf("RMode[%d],M1[%f]M2[%f],LE[%d],RE[%d]\n",
00078                                 itsRemoteMode,
00079                                 itsMotor1Speed,
00080                                 itsMotor2Speed,
00081                                 itsLeftEncoder,
00082                                 itsRightEncoder
00083                 );
00084                 UpdatePosition();
00085                 
00086         }
00087         else
00088         {
00089                 //printf("BAD FRAME RECIEVED!");
00090         }
00091 }
00092 unsigned int BeoPilot::getRCChannel(int channel)
00093 {
00094         if(channel < 0 || channel > 7)
00095                 return 0;
00096 
00097         unsigned char cmd[2] = {104, channel};
00098 
00099         itsSerial->write(cmd, 2);
00100         std::vector<unsigned char> frame = itsSerial->readFrame(cmd[0], 255);
00101 
00102         if(frame.size() == 4)
00103         {
00104                 unsigned int val = ((0x0FF & frame[0]) << 24) |
00105                                    ((0x0FF & frame[1]) << 16) |
00106                                    ((0x0FF & frame[2]) <<  8) |
00107                                    ((0x0FF & frame[3]) <<  0);
00108                 return val;
00109         }
00110         else
00111                 printf("Bad Frame Size! (%lu)", frame.size());
00112 
00113         return 0;
00114 
00115 }
00116 
00117 unsigned char BeoPilot::getRCStatus()
00118 {
00119         unsigned char cmd = 103;
00120 
00121         itsSerial->write(cmd);
00122         std::vector<unsigned char> frame = itsSerial->readFrame(cmd, 255);
00123 
00124         if(frame.size() == 1)
00125                 return frame[0];
00126 
00127         else
00128                 printf("Bad Frame Size! (%lu)", frame.size());
00129         return 0;
00130 
00131 }
00132 
00133 unsigned char BeoPilot::getRCEnabled()
00134 {
00135         unsigned char cmd = 105;
00136 
00137         itsSerial->write(cmd);
00138         std::vector<unsigned char> frame = itsSerial->readFrame(cmd, 255);
00139 
00140         if(frame.size() == 1)
00141                 return frame[0];
00142         else
00143                 printf("Bad Frame Size! (%lu)", frame.size());
00144         return 0;
00145 }
00146 
00147 unsigned int BeoPilot::getRCSpeed()
00148 {
00149         unsigned char cmd = 106;
00150 
00151         itsSerial->write(cmd);
00152         std::vector<unsigned char> frame = itsSerial->readFrame(cmd, 255);
00153 
00154         if(frame.size() == 4)
00155         {
00156                 unsigned int val = ((0x0FF & frame[0]) << 24) |
00157                         ((0x0FF & frame[1]) << 16) |
00158                         ((0x0FF & frame[2]) <<  8) |
00159                         ((0x0FF & frame[3]) <<  0);
00160                 return val;
00161         }
00162         else
00163                 printf("Bad Frame Size! (%lu)", frame.size());
00164 
00165         return 0;
00166 
00167 }
00168 // ######################################################################
00169 void BeoPilot::SetMotorsPid(float rotationalSpeed, float translationalSpeed)
00170 {
00171 
00172         double currentRot = (itsLeftMotorVelocity - itsRightMotorVelocity)/2;
00173         double currentTrans = (itsLeftMotorVelocity + itsRightMotorVelocity)/2;
00174         double rotErr = currentRot - rotationalSpeed;
00175         double transErr = currentTrans - translationalSpeed;
00176 
00177         double pidRot = itsPidRot.updatePid(rotErr,dt);
00178         double pidTrans = itsPidSpeed.updatePid(transErr,dt);
00179 
00180         SetMotors(pidRot,pidTrans);
00181         
00182 
00183 
00184 }
00185 // ######################################################################
00186 void BeoPilot::SetMotors(float rotationalSpeed, float translationalSpeed)
00187 {
00188         //Clamp the motor speeds to [-1 .. 1]
00189 
00190         //float vx = itsVelocity.x;
00191         //float vy = itsVelocity.y;
00192         //float th = itsVelocity.z;
00193         
00194 
00195 
00196 
00197 
00198         if(rotationalSpeed > 1.0)
00199                 rotationalSpeed = 1.0;
00200         if(rotationalSpeed < -1.0)
00201                 rotationalSpeed = -1.0;
00202         if(translationalSpeed > 1.0)
00203                 translationalSpeed = 1.0;
00204         if(translationalSpeed < -1.0)
00205                 translationalSpeed = -1.0;
00206 
00207         char rotSpeed  = char(rotationalSpeed    * 100.0);
00208         char tranSpeed = char(translationalSpeed * 100.0);
00209 
00210                 
00211 
00212         //Send the command for the first motor
00213         unsigned char cmd[3];
00214         cmd[0] = 100;             //Command: Set Motor 1
00215         cmd[1] = rotSpeed;                                 //Command: Rotational Speed?
00216         itsSerial->write(cmd, 2);
00217         usleep(10000);
00218 
00219         //Send the command for the second motor
00220         cmd[0] = 101;             //Command: Set Motor 2
00221         cmd[1] = tranSpeed;       //Command: Translational Speed?
00222         itsSerial->write(cmd, 2);
00223         usleep(10000);
00224 }
00225 
00226 
00227 // We have 10 inch diameter wheel
00228 // Motor Shaft will turn 21 times for one wheel spin
00229 // The encoder have 4000 tick per revolution
00230 // When the wheel have one revolution, it travels 10 * pi inch
00231 //
00232 // 10* pi inch  = 0.797964534 meters
00233 // Which have 1000 * 21 ticks
00234 //  (10 * pi)/84,000 * 0.0254 =  9.49957779 * 10^(-6) = 0.000009.49957779 meter
00235 // Which means for every tick,
00236 // the wheel will move  meter
00237 //
00238 // Width between two wheel W = 510 mm = 0.51m
00239 // To convert odometry data to position, we need do some math again...
00240 // Ot+1 = Ot + (Dr - Dl) / W
00241 // Dt,t+1 = (Dr + Dl) / 2
00242 // Xt+1 = Xt + Dt,t+1 * cos(Ot+1)
00243 // Yt+1 = Yt + Dt,t+1 * sin(Ot+1)
00244 void BeoPilot::UpdatePosition(void)
00245 {
00246         if(itsLastRightEncoder == 0.0 && itsLastLeftEncoder == 0.0)
00247                 itsPreviousTime = ros::Time::now();
00248         dt = ros::Time::now() - itsPreviousTime;
00249         double time = dt.toSec();
00250         //double time = (double) itsEncoderTimer.getReset()/1000000.0;//sec
00251 
00252 //        double meterPerTick = 0.00000949957779 ;
00253         double ticksPerMeter = 105267.836;
00254         double dr = (itsRightEncoder - itsLastRightEncoder) / ticksPerMeter;
00255         double dl = (itsLeftEncoder - itsLastLeftEncoder)  / ticksPerMeter;
00256         double w = 0.51;
00257         double ot = itsPosition.z + ((dr - dl) / w );
00258         double dt = (dr + dl)/2;
00259         double xt = itsPosition.x + dt * cos(ot);
00260         double yt = itsPosition.y + dt * sin(ot);
00261 
00262 
00263         // compute motor velocity
00264         if(time != 0.0){
00265                 itsLeftMotorVelocity = -(dl/time);
00266                 itsRightMotorVelocity = -(dr/time);
00267         }
00268         printf("Time[%f] Left V %f Right V %f,dl %f,dr %f",time,itsLeftMotorVelocity,
00269                         itsRightMotorVelocity,dl,dr);
00270 
00271         // the difference in position between the current and previous time step
00272         itsDiffPosition.x = dt * cos(ot);
00273         itsDiffPosition.y = dt * sin(ot);
00274         itsDiffPosition.z = ((dr - dl) / w ); //use z as orientation data
00275 
00276         itsVelocity.x = itsDiffPosition.x/time;
00277         itsVelocity.y = itsDiffPosition.y/time;
00278         itsVelocity.z = itsDiffPosition.z/time;
00279         itsPosition.x = xt;
00280         itsPosition.y = yt;
00281         itsPosition.z = ot;//use z as orientation data
00282 
00283 }
00284 
00285 void BeoPilot::resetEncoder()
00286 {
00287 
00288         unsigned char cmd = 108;
00289         itsSerial->write(cmd);
00290 
00291         itsPosition.x = 0;
00292         itsPosition.y = 0;
00293         itsPosition.z = 0;
00294         itsDiffPosition.x = 0;
00295         itsDiffPosition.y = 0;
00296         itsDiffPosition.z = 0;
00297 
00298         itsVelocity.x = 0;
00299         itsVelocity.y = 0;
00300         itsVelocity.z = 0;
00301         itsPidSpeed.reset();
00302         itsPidRot.reset();
00303 
00304 }
Generated on Sun May 8 08:05:35 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3