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
00017
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
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
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
00189
00190
00191
00192
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
00213 unsigned char cmd[3];
00214 cmd[0] = 100;
00215 cmd[1] = rotSpeed;
00216 itsSerial->write(cmd, 2);
00217 usleep(10000);
00218
00219
00220 cmd[0] = 101;
00221 cmd[1] = tranSpeed;
00222 itsSerial->write(cmd, 2);
00223 usleep(10000);
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
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
00251
00252
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
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
00272 itsDiffPosition.x = dt * cos(ot);
00273 itsDiffPosition.y = dt * sin(ot);
00274 itsDiffPosition.z = ((dr - dl) / w );
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;
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 }