00001 #include <CommsManager.H>
00002 #include <RobotDrive.H>
00003 #include <Egomotion.H>
00004 #include <Power.H>
00005 #include <RobotUtil.H>
00006 #include <RangeFinder.H>
00007 #include "RFlex.H"
00008 #include <cmath>
00009 #include <Logger.H>
00010
00011 using namespace WURDE;
00012 using namespace std;
00013
00014 string parseRflexConfig(std::string config,std::string rflexName);
00015
00016 CommsManager myManager("TomRFlex");
00017
00018 void handler(int signum){
00019 myManager.setQuit();
00020 }
00021
00022 int main(int argc, char *argv[]){
00023
00024 myManager.setRealName("RFlexServer");
00025 myManager.setHelpString("\t-c: Specify a config file to use. Default is rflex-config.xml\n\n Note that the -n flag is used to select the configuration block to be used from the config file.\n\nThis module provides access to the RFlex controller on iRobot/RWI B21r and ATRV Jr. robots. It has not been tested with other iRobot/RWI robots.\n\n");
00026 myManager.parseOptions(argc,argv,"c:");
00027 Logger myLogger(myManager.getName());
00028
00029 string port,confFile,robotType;
00030 bool unsafeBrake=false;
00031 unsigned char type=0;
00032 if(g_globalConfiguration.haveOption("c")){
00033 confFile=g_globalConfiguration.getOption("c");
00034 if(confFile[0]!='/'){
00035 confFile=g_globalConfiguration.getConfigDirectory()+"/"+confFile;
00036 }
00037 }else{
00038 confFile=g_globalConfiguration.getConfigDirectory()+"/"+"rflex-config.xml";
00039 }
00040
00041 g_logdebug << "Reading configuration for " << myManager.getName() << endl;
00042 port=parseRflexConfig(confFile,myManager.getName());
00043
00044 if(g_globalConfiguration.getOption("rFlexUnsafeBrake")=="true"){
00045 unsafeBrake=true;
00046 }
00047
00048 double trans=0, steer=0, tlimit=1.0, slimit=M_PI/2.0;
00049
00050 if(g_globalConfiguration.haveOption("rFlexMaxTrans")){
00051 tlimit=strtod(g_globalConfiguration.getOption("rFlexMaxTrans").c_str(),NULL);
00052 }
00053
00054 if(g_globalConfiguration.haveOption("rFlexMaxSteer")){
00055 slimit=strtod(g_globalConfiguration.getOption("rFlexMaxSteer").c_str(),NULL);
00056 }
00057
00058 if(g_globalConfiguration.haveOption("rFlexType")){
00059 robotType=g_globalConfiguration.getOption("rFlexType");
00060
00061 }else{
00062 robotType="B21r";
00063 }
00064
00065 RFlex rflex(port,robotType);
00066
00067 rflex.setBrake();
00068 rflex.systemUpdate();
00069 rflex.motorSetVelocity(0,0);
00070 rflex.odometryOn();
00071 rflex.systemUpdate();
00072
00073 RobotDrive myDrive(myManager.getName()+"Drive");
00074 Egomotion myEgomotion(myManager.getName()+"Motion");
00075 Power myPower(myManager.getName()+"Power");
00076 RangeFinder mySonar(myManager.getName()+"Sonar");
00077
00078 if(robotType=="B21r"){
00079 type=RFLEX_B21R;
00080 }else if(robotType=="ATRVJr"){
00081 type=RFLEX_ATRVJR;
00082 }
00083
00084 Pose currentPose(0,0,0);
00085 bool brakestat=true;
00086
00087 double baseX, baseY, baseT;
00088
00089
00090 usleep(2000);
00091
00092 baseX=rflex.x();
00093 baseY=rflex.y();
00094 baseT=rflex.heading();
00095
00096 myManager.registerSupplier(&myLogger);
00097 myManager.registerSupplier(&myDrive);
00098 myManager.registerSupplier(&myEgomotion);
00099 myManager.registerSupplier(&myPower);
00100 if(type==RFLEX_ATRVJR){
00101 myManager.registerSupplier(&mySonar);
00102 rflex.sonarOn();
00103 g_logdebug << "Turning on sonar..." << endl;
00104 for(int i=0;i<rflex.getNumSonars();i++){
00105 mySonar.data.ranges.push_back(0);
00106 }
00107 mySonar.info.uniform.setValueAndLock(false);
00108 mySonar.info.half_angle.setValueAndLock((7.5/180)*M_PI);
00109 mySonar.info.angle_min.setValueAndLock(0);
00110
00111 vector<Pose3D> tmpPositions(rflex.getNumSonars());
00112 for(int i=0;i<rflex.getNumSonars();i++){
00113 tmpPositions[i]=Pose3D(0,0,0.33);
00114 }
00115
00116 mySonar.info.sensor_positions.setValueAndLock(tmpPositions);
00117 mySonar.publishInfo();
00118 }
00119 myManager.setSleep(0.02);
00120
00121
00122
00123
00124 myDrive.info.transLimit.setValue(tlimit);
00125 myDrive.info.angularLimit.setValue(slimit);
00126
00127
00128 myDrive.info.transAccel.setValue(-1);
00129 myDrive.info.angularAccel.setValue(-1);
00130 myDrive.info.transDecel.setValue(-1);
00131 myDrive.info.angularDecel.setValue(-1);
00132
00133 myDrive.info.brake.setValue(true);
00134
00135
00136 myDrive.info.trans.setValue(0);
00137 myDrive.info.angular.setValue(0);
00138
00139 myDrive.publishInfo();
00140
00141 myEgomotion.data.location=currentPose;
00142 myEgomotion.data.transVelocity=0;
00143 myEgomotion.data.angularVelocity=0;
00144 myEgomotion.data.transAccel=0;
00145 myEgomotion.data.angularAccel=0;
00146
00147 myEgomotion.publishData();
00148
00149
00150
00151 myPower.data.volts=rflex.batteryVoltage();
00152
00153 myPower.data.max_volts=25.0;
00154 myPower.data.min_volts=21.0;
00155
00156
00157 myPower.data.ac_online=false;
00158 myPower.publishData();
00159
00160 while(myManager.runUpdate()==STATE_RUN||
00161 myManager.getState()==STATE_IDLE){
00162
00163 if(myManager.getState()==STATE_IDLE){
00164 rflex.motorSetVelocity(0,0);
00165 continue;
00166 }
00167
00168 rflex.systemUpdate();
00169
00170 if(myDrive.newRequest()){
00171
00172 myDrive.getNextRequest();
00173 tlimit=myDrive.requests.transLimit.getValue();
00174 slimit=myDrive.requests.angularLimit.getValue();
00175 trans=myDrive.requests.trans.getValue();
00176 steer=myDrive.requests.angular.getValue();
00177
00178 g_logdebug << "Received request: (trans,steer) " << trans << "," << steer << endl;
00179
00180 if(myDrive.requests.brake.getValue()){
00181
00182 g_debug("Activating brake");
00183 rflex.setBrake();
00184 brakestat=true;
00185 }else{
00186
00187 g_debug("Turning off software brake. Hardware brake may still be active.");
00188
00189
00190
00191
00192
00193
00194 if(unsafeBrake){
00195 rflex.brakeOff();
00196 }
00197 brakestat=false;
00198 }
00199
00200 if(trans>tlimit)
00201 trans=tlimit;
00202 else if(trans<(-tlimit))
00203 trans=(-tlimit);
00204
00205 if(steer>slimit)
00206 steer=slimit;
00207 else if(steer<(-slimit))
00208 steer=(-slimit);
00209
00210 }
00211
00212
00213 if(!brakestat){
00214 rflex.motorSetVelocity(trans,steer);
00215 }else{
00216 rflex.motorSetVelocity(0,0);
00217 }
00218
00219 myDrive.info.trans.setValue(trans);
00220 myDrive.info.angular.setValue(steer);
00221 myDrive.info.transLimit.setValue(tlimit);
00222 myDrive.info.angularLimit.setValue(slimit);
00223 myDrive.info.brake.setValue(rflex.brakeOn());
00224 myDrive.publishInfo();
00225
00226 currentPose.x(rflex.x());
00227 currentPose.y(rflex.y());
00228 currentPose.theta(rflex.heading());
00229
00230 g_logdebug << "current pose " << rflex.x() << " " << rflex.y() << " " << rflex.heading() << endl;
00231
00232 myEgomotion.data.location=currentPose;
00233 myEgomotion.data.transVelocity=rflex.translateVelocity();
00234 myEgomotion.data.angularVelocity=rflex.rotateVelocity();
00235 myEgomotion.data.transAccel=rflex.translateAcceleration();
00236 myEgomotion.data.angularAccel=rflex.rotateAcceleration();
00237
00238 myEgomotion.publishData();
00239
00240 if(type==RFLEX_ATRVJR){
00241 for(int i=0;i<rflex.getNumSonars();i++){
00242 mySonar.data.ranges[i]=rflex.getSonar(i);
00243 }
00244
00245 mySonar.publishData();
00246 }
00247
00248 myPower.data.volts=rflex.batteryVoltage();
00249 myPower.publishData();
00250
00251 }
00252
00253
00254 rflex.motorSetVelocity(0,0);
00255
00256 if(type==RFLEX_ATRVJR){
00257 rflex.sonarOff();
00258 }
00259
00260 myDrive.info.trans.setValue(0);
00261 myDrive.info.angular.setValue(0);
00262 myDrive.info.transLimit.setValue(tlimit);
00263 myDrive.info.angularLimit.setValue(slimit);
00264 myDrive.publishInfo();
00265
00266 currentPose.x(0);
00267 currentPose.y(0);
00268 currentPose.theta(0);
00269 myEgomotion.data.location=currentPose;
00270 myEgomotion.data.transVelocity=0;
00271 myEgomotion.data.angularVelocity=0;
00272 myEgomotion.data.transAccel=0;
00273 myEgomotion.data.angularAccel=0;
00274
00275 myEgomotion.publishData();
00276 g_debug("Shutting down rFlex cleanly.");
00277 myManager.runUpdate();
00278
00279 myManager.cleanUp();
00280
00281 return 0;
00282 }