My Version of CreaBotLib

Fork of CreaBotLib by CreaLab

Committer:
sepp_nepp
Date:
Thu Apr 18 12:06:07 2019 +0000
Revision:
12:530772639065
Parent:
11:5a94af0afa12
Compiles

Who changed what in which revision?

UserRevisionLine numberNew contents of line
garphil 0:a7fb03c9ea9d 1 #include "CreaBot.h"
garphil 0:a7fb03c9ea9d 2
sepp_nepp 5:efe80c5db389 3 // *****************************************************************
sepp_nepp 6:4d8938b686a6 4 // BotCommand Structure Helper
sepp_nepp 5:efe80c5db389 5 // *****************************************************************
sepp_nepp 5:efe80c5db389 6
sepp_nepp 6:4d8938b686a6 7 // Struct Helper; set structure fields to values */
sepp_nepp 9:efe9f76d6f76 8 void BotCommand::set(BotCmdVerb Acommand, float Aturn_angle_deg, float Adist_cm)
sepp_nepp 6:4d8938b686a6 9 { command = Acommand;
sepp_nepp 6:4d8938b686a6 10 dist_cm = Adist_cm;
sepp_nepp 9:efe9f76d6f76 11 turn_angle_deg= Aturn_angle_deg;
sepp_nepp 6:4d8938b686a6 12 };
sepp_nepp 6:4d8938b686a6 13
sepp_nepp 6:4d8938b686a6 14 // Struct Helper; set structure fields to values */
sepp_nepp 7:3a793ddc3490 15 void BotCommand::set(BotCmdVerb Acommand, float Aparam)
sepp_nepp 6:4d8938b686a6 16 { command = Acommand;
sepp_nepp 7:3a793ddc3490 17 dist_cm = Aparam;
sepp_nepp 9:efe9f76d6f76 18 turn_angle_deg= Aparam;
sepp_nepp 5:efe80c5db389 19 };
sepp_nepp 5:efe80c5db389 20
sepp_nepp 5:efe80c5db389 21
sepp_nepp 5:efe80c5db389 22 // *****************************************************************
sepp_nepp 5:efe80c5db389 23 // Creabot Class
sepp_nepp 5:efe80c5db389 24 // *****************************************************************
sepp_nepp 5:efe80c5db389 25
sepp_nepp 10:79509113310a 26 Creabot::Creabot(CreaMot *left, CreaMot *right, float diameter_wheel_cm, float bot_diam_cm):
sepp_nepp 10:79509113310a 27 wheelLeft(left), wheelRight(right)
garphil 0:a7fb03c9ea9d 28 {
sepp_nepp 9:efe9f76d6f76 29 // TODO: To catch for illegal dimensions (<= 0)
sepp_nepp 9:efe9f76d6f76 30
sepp_nepp 9:efe9f76d6f76 31 // Initialize wheel geometires
sepp_nepp 11:5a94af0afa12 32 wheelLeft ->setDiamCM( diameter_wheel_cm );
sepp_nepp 11:5a94af0afa12 33 wheelRight->setDiamCM( diameter_wheel_cm );
sepp_nepp 9:efe9f76d6f76 34 // setup the bot parameters:
sepp_nepp 10:79509113310a 35 botDiameter = bot_diam_cm;
sepp_nepp 10:79509113310a 36 ratio_wheel_bot = bot_diam_cm/diameter_wheel_cm;
sepp_nepp 9:efe9f76d6f76 37 botSpeed_cm_sec = DEFAULT_SPEED_CM_SEC;
garphil 0:a7fb03c9ea9d 38
sepp_nepp 9:efe9f76d6f76 39 // Attach the Crabot functions as callbacks to the wheels
sepp_nepp 9:efe9f76d6f76 40 wheelLeft ->callbackSet(this, &Creabot::wheelLeftStoppedCB);
sepp_nepp 9:efe9f76d6f76 41 wheelRight->callbackSet(this, &Creabot::wheelRightStoppedCB);
sepp_nepp 6:4d8938b686a6 42 // Initialize own callback as empty
garphil 0:a7fb03c9ea9d 43 extCallBack = NULL;
sepp_nepp 6:4d8938b686a6 44
sepp_nepp 9:efe9f76d6f76 45 // setup the default Directions and State Values:
sepp_nepp 9:efe9f76d6f76 46 // used below as variable instead of always passing a direction
sepp_nepp 9:efe9f76d6f76 47 wheelLeft ->defaultDirection = COUNTERCLOCKWISE;
sepp_nepp 9:efe9f76d6f76 48 wheelLeft ->StateValue = LWHEEL_RUNS;
sepp_nepp 9:efe9f76d6f76 49 wheelRight->defaultDirection = CLOCKWISE;
sepp_nepp 9:efe9f76d6f76 50 wheelRight->StateValue = RWHEEL_RUNS;
sepp_nepp 9:efe9f76d6f76 51
sepp_nepp 6:4d8938b686a6 52 // Initialize the own status fields
sepp_nepp 9:efe9f76d6f76 53 wheelsState = LRWHEELS_STOP;
sepp_nepp 9:efe9f76d6f76 54 qReset();
garphil 0:a7fb03c9ea9d 55 }
garphil 0:a7fb03c9ea9d 56
sepp_nepp 9:efe9f76d6f76 57
sepp_nepp 9:efe9f76d6f76 58 // *****************************************************************
sepp_nepp 9:efe9f76d6f76 59 // Queue Queue management
sepp_nepp 9:efe9f76d6f76 60 // *****************************************************************
sepp_nepp 9:efe9f76d6f76 61
sepp_nepp 9:efe9f76d6f76 62 void Creabot::qMove(BotCmdVerb Acommand, float Aparam)
garphil 0:a7fb03c9ea9d 63 {
sepp_nepp 9:efe9f76d6f76 64 qMove(Acommand, Aparam, Aparam);
sepp_nepp 5:efe80c5db389 65 }
garphil 0:a7fb03c9ea9d 66
sepp_nepp 9:efe9f76d6f76 67 /* Add a new movement to the queue, if not full.
sepp_nepp 9:efe9f76d6f76 68 * ATTENTION:
sepp_nepp 9:efe9f76d6f76 69 * qExecuteNext() is called asynchronsously by the motor Callback wheelsAllStoppedCB()
sepp_nepp 9:efe9f76d6f76 70 * qExecuteNext() tries to read access the next command in the queue.
sepp_nepp 9:efe9f76d6f76 71 * A simultaneous read and write access to the same resources can lead to
sepp_nepp 9:efe9f76d6f76 72 * conflict and must be carefully avoided.
sepp_nepp 9:efe9f76d6f76 73 * This conflict concerns the read-modify-write access of variable Count.
sepp_nepp 9:efe9f76d6f76 74 * It is avoided by using the qBlock variable. With qBlock set during increment
sepp_nepp 9:efe9f76d6f76 75 * a simultaneous read access is blocked
sepp_nepp 9:efe9f76d6f76 76 * Any changes to those write and read handlers must take into account that
sepp_nepp 9:efe9f76d6f76 77 * wheelsAllStoppedCB() and qExecuteNext() may be called any time while
sepp_nepp 9:efe9f76d6f76 78 * executing qMove command.
sepp_nepp 9:efe9f76d6f76 79 */
sepp_nepp 9:efe9f76d6f76 80 void Creabot::qMove(BotCmdVerb Acommand, float Aturn_angle_deg, float Adist_cm)
sepp_nepp 9:efe9f76d6f76 81 { if( !qIsFull() )
sepp_nepp 9:efe9f76d6f76 82 { cmd[writeIdx].set(Acommand, Aturn_angle_deg, Adist_cm);
sepp_nepp 9:efe9f76d6f76 83 writeIdx++;
sepp_nepp 9:efe9f76d6f76 84 if (writeIdx==DEPTH_Queue) writeIdx=0;
sepp_nepp 9:efe9f76d6f76 85 qCollide = false; // colliding access to qCollide cannot happen while qBlock = false
sepp_nepp 9:efe9f76d6f76 86 // if callback happens here, there is no collosion, the last old command gets already executed.
sepp_nepp 9:efe9f76d6f76 87 qBlock = true;
sepp_nepp 9:efe9f76d6f76 88 // if callback happens here while qBlock = true, the collision is remembered in qCollide
sepp_nepp 9:efe9f76d6f76 89 Count++;
sepp_nepp 9:efe9f76d6f76 90 qBlock = false;
sepp_nepp 9:efe9f76d6f76 91 // if callback happens here there is no more blockage and the next (maybe the new) command is already being executed
sepp_nepp 9:efe9f76d6f76 92 // in this case qCollide = false, and wheelsState!=LRWHEELS_STOP
sepp_nepp 9:efe9f76d6f76 93 if ( qCollide || (wheelsState==LRWHEELS_STOP) )
sepp_nepp 9:efe9f76d6f76 94 // callback cannot happen here since the wheelState is already STOP, or Collide has happened before!
sepp_nepp 10:79509113310a 95 qExecuteNext();
sepp_nepp 9:efe9f76d6f76 96 };
sepp_nepp 5:efe80c5db389 97 }
sepp_nepp 5:efe80c5db389 98
sepp_nepp 9:efe9f76d6f76 99
sepp_nepp 9:efe9f76d6f76 100 // Queue is worked through while still any elements inside
sepp_nepp 9:efe9f76d6f76 101 // ATTENTION read above consideration of conflicting accesses between qMove() and wheelsAllStoppedCB()
sepp_nepp 9:efe9f76d6f76 102 // Think careful if a case can occur that pExecuteNext is called twice immediately following each other,
sepp_nepp 9:efe9f76d6f76 103 // once by qMove() and once by wheelsAllStoppedCB() ???
sepp_nepp 9:efe9f76d6f76 104 void Creabot::qExecuteNext()
sepp_nepp 9:efe9f76d6f76 105 { if ( !qIsEmpty() ) // see if something in the queue to execute
sepp_nepp 9:efe9f76d6f76 106 { // Execute and then remove the oldest element at the tail of the Queue
sepp_nepp 10:79509113310a 107 iExeCommand( &cmd[readIdx] );
sepp_nepp 9:efe9f76d6f76 108 readIdx++;
sepp_nepp 9:efe9f76d6f76 109 if (readIdx==DEPTH_Queue) readIdx=0;
sepp_nepp 9:efe9f76d6f76 110 Count--;
sepp_nepp 9:efe9f76d6f76 111 };
sepp_nepp 5:efe80c5db389 112 }
sepp_nepp 5:efe80c5db389 113
sepp_nepp 9:efe9f76d6f76 114 // Immediately end All, the queue and the motor
sepp_nepp 9:efe9f76d6f76 115 void Creabot::qStopAll()
sepp_nepp 9:efe9f76d6f76 116 { qReset(); // empty the queue
sepp_nepp 9:efe9f76d6f76 117 iStop(); // stop the motors, do not call external callback
sepp_nepp 9:efe9f76d6f76 118 }
sepp_nepp 9:efe9f76d6f76 119
sepp_nepp 5:efe80c5db389 120
sepp_nepp 7:3a793ddc3490 121 //**************************************************************************
sepp_nepp 7:3a793ddc3490 122 // Using the BotCmdVerb to encode different commands, done immediately
sepp_nepp 7:3a793ddc3490 123 //**************************************************************************
sepp_nepp 7:3a793ddc3490 124
sepp_nepp 9:efe9f76d6f76 125 void Creabot::iMoveAndWait(BotCmdVerb moveType, float Aparam)
sepp_nepp 10:79509113310a 126 { iMove(moveType,Aparam,Aparam);
sepp_nepp 10:79509113310a 127 iWaitEnd();
sepp_nepp 5:efe80c5db389 128 }
sepp_nepp 5:efe80c5db389 129
sepp_nepp 9:efe9f76d6f76 130 void Creabot::iMoveAndWait(BotCmdVerb moveType, float Aturn_angle_deg, float Adist_cm)
sepp_nepp 10:79509113310a 131 { iMove(moveType,Aturn_angle_deg,Adist_cm);
sepp_nepp 10:79509113310a 132 iWaitEnd();
sepp_nepp 5:efe80c5db389 133 }
sepp_nepp 5:efe80c5db389 134
sepp_nepp 9:efe9f76d6f76 135 void Creabot::iMove(BotCmdVerb moveType, float Aparam)
sepp_nepp 10:79509113310a 136 { iMove(moveType, Aparam, Aparam); }
sepp_nepp 7:3a793ddc3490 137
sepp_nepp 9:efe9f76d6f76 138 void Creabot::iMove(BotCmdVerb moveType, float Aturn_angle_deg, float Adist_cm)
sepp_nepp 7:3a793ddc3490 139 { BotCommand Anew_cmd;
sepp_nepp 9:efe9f76d6f76 140 Anew_cmd.set(moveType, Aturn_angle_deg, Adist_cm);
sepp_nepp 10:79509113310a 141 iExeCommand(&Anew_cmd);
sepp_nepp 7:3a793ddc3490 142 }
sepp_nepp 7:3a793ddc3490 143
sepp_nepp 9:efe9f76d6f76 144 /** High level, immediate: move bot according to prefilled command structures.
sepp_nepp 10:79509113310a 145 * Recommended to use iMove() methods to fill the command structure correctly.
sepp_nepp 9:efe9f76d6f76 146 * Branches to the moveXXXX() methods. For details see docs for those methods.
sepp_nepp 9:efe9f76d6f76 147 * Warning: Collides with queued commands if called individually.
sepp_nepp 9:efe9f76d6f76 148 * @param[in] <*cmd> Pointer to type BotCommand, the prefilled command structure,*/
sepp_nepp 9:efe9f76d6f76 149 void Creabot::iExeCommand(BotCommand *cmd) {
garphil 0:a7fb03c9ea9d 150 switch (cmd->command) {
garphil 0:a7fb03c9ea9d 151 case FORWARD:
sepp_nepp 6:4d8938b686a6 152 moveForward(cmd->dist_cm);
garphil 0:a7fb03c9ea9d 153 break;
garphil 0:a7fb03c9ea9d 154 case BACKWARD:
sepp_nepp 6:4d8938b686a6 155 moveBackward(cmd->dist_cm);
garphil 0:a7fb03c9ea9d 156 break;
garphil 0:a7fb03c9ea9d 157 case LEFT:
sepp_nepp 9:efe9f76d6f76 158 moveLeft(cmd->turn_angle_deg, cmd->dist_cm);
garphil 0:a7fb03c9ea9d 159 break;
garphil 0:a7fb03c9ea9d 160 case RIGHT:
sepp_nepp 9:efe9f76d6f76 161 moveRight(cmd->turn_angle_deg, cmd->dist_cm);
sepp_nepp 9:efe9f76d6f76 162 break;
sepp_nepp 9:efe9f76d6f76 163 case BACKLEFT:
sepp_nepp 9:efe9f76d6f76 164 moveBackLeft(cmd->turn_angle_deg, cmd->dist_cm);
sepp_nepp 9:efe9f76d6f76 165 break;
sepp_nepp 9:efe9f76d6f76 166 case BACKRIGHT:
sepp_nepp 9:efe9f76d6f76 167 moveBackRight(cmd->turn_angle_deg, cmd->dist_cm);
sepp_nepp 9:efe9f76d6f76 168 break;
sepp_nepp 9:efe9f76d6f76 169 case ROTATE:
sepp_nepp 9:efe9f76d6f76 170 moveRotate(cmd->turn_angle_deg);
garphil 0:a7fb03c9ea9d 171 break;
garphil 0:a7fb03c9ea9d 172 default:
garphil 0:a7fb03c9ea9d 173 break;
garphil 0:a7fb03c9ea9d 174 };
sepp_nepp 5:efe80c5db389 175 }; // executeCommand
sepp_nepp 5:efe80c5db389 176
sepp_nepp 9:efe9f76d6f76 177 /* spends all time with waits, returns only once wheelState = LRWHEELS_STOP */
sepp_nepp 9:efe9f76d6f76 178 void Creabot::iWaitEnd()
sepp_nepp 9:efe9f76d6f76 179 { while(wheelsState!=LRWHEELS_STOP) wait(0.1); }
sepp_nepp 6:4d8938b686a6 180
sepp_nepp 9:efe9f76d6f76 181 /* spends all time with waits, returns only once wheelState = LRWHEELS_STOP,
sepp_nepp 9:efe9f76d6f76 182 but maximum max_wait_ms milli seconds */
sepp_nepp 9:efe9f76d6f76 183 void Creabot::iWaitEnd(uint32_t max_wait_ms)
sepp_nepp 9:efe9f76d6f76 184 { uint32_t waited=0;
sepp_nepp 9:efe9f76d6f76 185 while( (wheelsState!=LRWHEELS_STOP) && (waited < max_wait_ms) )
sepp_nepp 9:efe9f76d6f76 186 { wait(0.1); waited += 100; }
sepp_nepp 9:efe9f76d6f76 187 } // botWaitEnd
garphil 0:a7fb03c9ea9d 188
sepp_nepp 9:efe9f76d6f76 189 void Creabot::iStop()
sepp_nepp 9:efe9f76d6f76 190 { // Call the StopRun method, so wheels detach their tickers
sepp_nepp 9:efe9f76d6f76 191 wheelLeft->StopRun();
sepp_nepp 9:efe9f76d6f76 192 wheelRight->StopRun();
sepp_nepp 9:efe9f76d6f76 193 // wheelsAllStoppedCB could handle the rest of the cleanup, but would also trigger external callback
sepp_nepp 9:efe9f76d6f76 194 // Turn motor power off!
sepp_nepp 10:79509113310a 195 wheelLeft->MotorOFF();
sepp_nepp 10:79509113310a 196 wheelRight->MotorOFF();
sepp_nepp 10:79509113310a 197 wheelsState = LRWHEELS_STOP;
sepp_nepp 9:efe9f76d6f76 198 }
sepp_nepp 7:3a793ddc3490 199
sepp_nepp 7:3a793ddc3490 200 // *****************************************************************
sepp_nepp 7:3a793ddc3490 201 // Creabot Mid level control functions:
sepp_nepp 9:efe9f76d6f76 202 // all directly access the wheel, no Queue */
sepp_nepp 7:3a793ddc3490 203 // *****************************************************************
sepp_nepp 7:3a793ddc3490 204
sepp_nepp 9:efe9f76d6f76 205 // set botSpeed_cm_sec parameter for next high level commands
sepp_nepp 9:efe9f76d6f76 206 void Creabot::setSpeed(float AbotSpeed_cm_sec)
sepp_nepp 9:efe9f76d6f76 207 { if (AbotSpeed_cm_sec > MAX_SPEED_CM_SEC) botSpeed_cm_sec = MAX_SPEED_CM_SEC;
sepp_nepp 9:efe9f76d6f76 208 else if (AbotSpeed_cm_sec<MIN_SPEED_CM_SEC) botSpeed_cm_sec = MIN_SPEED_CM_SEC;
sepp_nepp 9:efe9f76d6f76 209 else botSpeed_cm_sec = AbotSpeed_cm_sec;
sepp_nepp 9:efe9f76d6f76 210 // Low level setting of wheel speed is done inside SetMotsSpeed:
sepp_nepp 7:3a793ddc3490 211 }
garphil 0:a7fb03c9ea9d 212
sepp_nepp 9:efe9f76d6f76 213 // Mid level control function: advance bot straight forward for a given distance
sepp_nepp 7:3a793ddc3490 214 void Creabot::moveForward(float dist_cm)
sepp_nepp 10:79509113310a 215 {
sepp_nepp 10:79509113310a 216 wheelsSetSpeed(botSpeed_cm_sec);
sepp_nepp 10:79509113310a 217 wheelRight->RunDist_cm(dist_cm );
sepp_nepp 10:79509113310a 218 wheelLeft ->RunDist_cm(dist_cm ); // Direction = defaultDirection
sepp_nepp 10:79509113310a 219 // negative distances are run by RunDist_cm in opposite direction!
sepp_nepp 10:79509113310a 220 wheelsState = LRWHEELS_RUN;
sepp_nepp 7:3a793ddc3490 221 }
sepp_nepp 7:3a793ddc3490 222
sepp_nepp 9:efe9f76d6f76 223 // Mid level control function: reverse bot straight backwards for a given distance
sepp_nepp 7:3a793ddc3490 224 void Creabot::moveBackward(float dist_cm)
sepp_nepp 7:3a793ddc3490 225 {
sepp_nepp 10:79509113310a 226 wheelsSetSpeed(botSpeed_cm_sec);
sepp_nepp 10:79509113310a 227 wheelRight->RunDist_cm(-dist_cm);
sepp_nepp 10:79509113310a 228 wheelLeft ->RunDist_cm(-dist_cm);// Direction = defaultDirection
sepp_nepp 10:79509113310a 229 // negative distance are run by RunDist_cm in opposite direction!
sepp_nepp 10:79509113310a 230 wheelsState = LRWHEELS_RUN;
sepp_nepp 7:3a793ddc3490 231 }
sepp_nepp 7:3a793ddc3490 232
sepp_nepp 7:3a793ddc3490 233 /* Mid level control function: turn bot forward right,
sepp_nepp 10:79509113310a 234 around a radius equl the bot size; i.e. turn around the right wheel */
sepp_nepp 9:efe9f76d6f76 235 void Creabot::moveRight(float turn_angle_deg)
sepp_nepp 5:efe80c5db389 236 {
sepp_nepp 9:efe9f76d6f76 237 wheelLeft->setSpeed_cm_sec(botSpeed_cm_sec);
sepp_nepp 10:79509113310a 238 wheelLeft->RunTurnAngle(turn_angle_deg,botDiameter);
sepp_nepp 10:79509113310a 239 wheelsState = LWHEEL_RUNS;
garphil 0:a7fb03c9ea9d 240 }
garphil 0:a7fb03c9ea9d 241
sepp_nepp 7:3a793ddc3490 242 /* Mid level control function: turn bot forward right,
sepp_nepp 10:79509113310a 243 around a radius that is turn_radius_cm away from the right wheel*/
sepp_nepp 9:efe9f76d6f76 244 void Creabot::moveRight(float turn_angle_deg, float turn_radius_cm)
sepp_nepp 10:79509113310a 245 { // If Center_cm is too small the right wheel has practically nothing to do ;)
sepp_nepp 11:5a94af0afa12 246 if (fabs(double(turn_radius_cm))<0.1) { moveRight(turn_angle_deg); }
sepp_nepp 10:79509113310a 247 else {
sepp_nepp 10:79509113310a 248 wheelLeft ->setSpeed_cm_sec(botSpeed_cm_sec);
sepp_nepp 10:79509113310a 249 wheelRight->setSpeed_cm_sec(botSpeed_cm_sec * turn_radius_cm/turn_radius_cm+botDiameter);
sepp_nepp 10:79509113310a 250 wheelRight->RunTurnAngle(turn_angle_deg,turn_radius_cm );
sepp_nepp 10:79509113310a 251 wheelLeft ->RunTurnAngle(turn_angle_deg,turn_radius_cm+botDiameter);// Direction = defaultDirection
sepp_nepp 10:79509113310a 252 // negative distance are run by RunTurnAngle in opposite direction!
sepp_nepp 10:79509113310a 253 wheelsState = LRWHEELS_RUN;
sepp_nepp 10:79509113310a 254 } // else
sepp_nepp 5:efe80c5db389 255 }
sepp_nepp 5:efe80c5db389 256
sepp_nepp 10:79509113310a 257 /* Mid level control function: turn bot backwards Right,
sepp_nepp 10:79509113310a 258 around a radius that is turn_radius_cm away from the Right wheel */
sepp_nepp 10:79509113310a 259 void Creabot::moveBackRight(float turn_angle_deg, float turn_radius_cm)
sepp_nepp 10:79509113310a 260 { moveRight( -turn_angle_deg , turn_radius_cm); }
sepp_nepp 10:79509113310a 261
sepp_nepp 10:79509113310a 262 /* Mid level control function: turn bot backwards Right,
sepp_nepp 10:79509113310a 263 around a radius equal to the bot size; = the Right wheel stands still */
sepp_nepp 10:79509113310a 264 void Creabot::moveBackRight(float turn_angle_deg)
sepp_nepp 10:79509113310a 265 { moveRight( - turn_angle_deg); }
sepp_nepp 9:efe9f76d6f76 266
sepp_nepp 7:3a793ddc3490 267 /* Mid level control function: turn bot forward left,
sepp_nepp 10:79509113310a 268 around a radius equal to the bot size; = the left wheel stands still */
sepp_nepp 9:efe9f76d6f76 269 void Creabot::moveLeft(float turn_angle_deg)
sepp_nepp 5:efe80c5db389 270 {
sepp_nepp 11:5a94af0afa12 271 wheelRight->setSpeed_cm_sec(botSpeed_cm_sec);
sepp_nepp 10:79509113310a 272 wheelRight->RunTurnAngle(turn_angle_deg,botDiameter);
sepp_nepp 10:79509113310a 273 wheelsState = RWHEEL_RUNS;
garphil 4:531b1120d3ec 274 }
garphil 4:531b1120d3ec 275
sepp_nepp 7:3a793ddc3490 276 /* Mid level control function: turn bot forward left,
sepp_nepp 10:79509113310a 277 around a radius that is turn_radius_cm away from the left wheel */
sepp_nepp 10:79509113310a 278 void Creabot::moveLeft(float turn_angle_deg, float turn_radius_cm)
sepp_nepp 10:79509113310a 279 { // If Center_cm is too small the left wheel has practically nothing to do ;)
sepp_nepp 11:5a94af0afa12 280 if (fabs(double(turn_radius_cm))<0.1) { moveLeft(turn_angle_deg); }
sepp_nepp 10:79509113310a 281 else {
sepp_nepp 10:79509113310a 282 wheelLeft -> setSpeed_cm_sec(botSpeed_cm_sec * turn_radius_cm/(turn_radius_cm+botDiameter));
sepp_nepp 10:79509113310a 283 wheelRight-> setSpeed_cm_sec(botSpeed_cm_sec);
sepp_nepp 10:79509113310a 284 wheelLeft -> RunTurnAngle(turn_angle_deg,turn_radius_cm);
sepp_nepp 10:79509113310a 285 wheelRight-> RunTurnAngle(turn_angle_deg,turn_radius_cm+botDiameter);// Direction = defaultDirection
sepp_nepp 10:79509113310a 286 // negative distance are run by RunTurnAngle in opposite direction!
sepp_nepp 10:79509113310a 287 wheelsState = LRWHEELS_RUN;
sepp_nepp 10:79509113310a 288 }
garphil 0:a7fb03c9ea9d 289 }
garphil 0:a7fb03c9ea9d 290
sepp_nepp 10:79509113310a 291 /* Mid level control function: turn bot backwards left,
sepp_nepp 10:79509113310a 292 around a radius that is turn_radius_cm away from the left wheel */
sepp_nepp 10:79509113310a 293 void Creabot::moveBackLeft(float turn_angle_deg, float turn_radius_cm)
sepp_nepp 10:79509113310a 294 { moveLeft( - turn_angle_deg, turn_radius_cm); }
sepp_nepp 10:79509113310a 295
sepp_nepp 10:79509113310a 296 /* Mid level control function: turn bot backwards left,
sepp_nepp 10:79509113310a 297 around a radius equal to the bot size; = the left wheel stands still */
sepp_nepp 10:79509113310a 298 void Creabot::moveBackLeft(float turn_angle_deg)
sepp_nepp 10:79509113310a 299 { moveLeft( - turn_angle_deg); }
sepp_nepp 10:79509113310a 300
sepp_nepp 7:3a793ddc3490 301 /* Mid level control function: turn bot on its place for a given angle.
sepp_nepp 7:3a793ddc3490 302 positive angles turn right, negative angles turn left*/
sepp_nepp 9:efe9f76d6f76 303 void Creabot::moveRotate(float angleBot)
garphil 0:a7fb03c9ea9d 304 {
sepp_nepp 7:3a793ddc3490 305 float angleWheel = angleBot*ratio_wheel_bot;
sepp_nepp 9:efe9f76d6f76 306 setSpeed(botSpeed_cm_sec);
sepp_nepp 7:3a793ddc3490 307 if(angleBot<0) {
sepp_nepp 10:79509113310a 308 wheelRight->RunDegrees( angleWheel);
sepp_nepp 10:79509113310a 309 wheelLeft ->RunDegrees(-angleWheel);// Direction = defaultDirection
sepp_nepp 10:79509113310a 310 // negative distance are run by RunDegrees in opposite direction!
sepp_nepp 7:3a793ddc3490 311 } else {
sepp_nepp 10:79509113310a 312 wheelLeft ->RunDegrees( angleWheel);
sepp_nepp 10:79509113310a 313 wheelRight->RunDegrees(-angleWheel);// Direction = defaultDirection
sepp_nepp 10:79509113310a 314 // negative distance are run by RunDegrees in opposite direction!
sepp_nepp 6:4d8938b686a6 315 }
sepp_nepp 10:79509113310a 316 wheelsState = LRWHEELS_RUN;
sepp_nepp 5:efe80c5db389 317 }
sepp_nepp 5:efe80c5db389 318
sepp_nepp 7:3a793ddc3490 319 //******************************************************************************
sepp_nepp 9:efe9f76d6f76 320 // low level wheel functions, only filters for rot_angle_deg>0, then passes
sepp_nepp 9:efe9f76d6f76 321 // to wheel Class; and remembers that a wheel moves
sepp_nepp 7:3a793ddc3490 322 //******************************************************************************
sepp_nepp 7:3a793ddc3490 323
sepp_nepp 9:efe9f76d6f76 324 /* Low level access functions: sets both wheel speeds immediately */
sepp_nepp 9:efe9f76d6f76 325 void Creabot::wheelsSetSpeed(float mot_speed_cm_sec)
sepp_nepp 5:efe80c5db389 326 {
sepp_nepp 10:79509113310a 327 wheelLeft ->setSpeed_cm_sec(mot_speed_cm_sec);
sepp_nepp 9:efe9f76d6f76 328 wheelRight->setSpeed_cm_sec(mot_speed_cm_sec);
sepp_nepp 5:efe80c5db389 329 }
sepp_nepp 5:efe80c5db389 330
sepp_nepp 7:3a793ddc3490 331 //******************************************************************************
sepp_nepp 9:efe9f76d6f76 332 // low level wheel functions, handles callbacks from wheels
sepp_nepp 7:3a793ddc3490 333 // *****************************************************************************
sepp_nepp 9:efe9f76d6f76 334
sepp_nepp 9:efe9f76d6f76 335 void Creabot::wheelLeftStoppedCB()
sepp_nepp 11:5a94af0afa12 336 { wheelsState = TWheelsState( wheelsState & LWHEEL_RUNS ); // mask out Left Wheel status bit
sepp_nepp 9:efe9f76d6f76 337 if (wheelsState == LRWHEELS_STOP) // all wheels are now known to have stopped
sepp_nepp 9:efe9f76d6f76 338 wheelsAllStoppedCB();
sepp_nepp 6:4d8938b686a6 339 }
sepp_nepp 6:4d8938b686a6 340
sepp_nepp 9:efe9f76d6f76 341 void Creabot::wheelRightStoppedCB()
sepp_nepp 11:5a94af0afa12 342 { wheelsState = TWheelsState( wheelsState & RWHEEL_RUNS ); // mask out Left Wheel status bit
sepp_nepp 9:efe9f76d6f76 343 if (wheelsState == LRWHEELS_STOP) // all wheels are now known to have stopped
sepp_nepp 9:efe9f76d6f76 344 wheelsAllStoppedCB();
sepp_nepp 7:3a793ddc3490 345 }
sepp_nepp 7:3a793ddc3490 346
sepp_nepp 9:efe9f76d6f76 347 void Creabot::wheelsAllStoppedCB()
sepp_nepp 9:efe9f76d6f76 348 { // assume that already at entry wheelsState == LRWHEELS_STOP
sepp_nepp 9:efe9f76d6f76 349 // Try to execute next entry in queue, if one is present
sepp_nepp 9:efe9f76d6f76 350 if ( !qBlock )
sepp_nepp 9:efe9f76d6f76 351 { qExecuteNext();// not blocked, so can execute now
sepp_nepp 9:efe9f76d6f76 352 // if wheels are still STOPed, that means no command to execute was left in the queue
sepp_nepp 9:efe9f76d6f76 353 if (wheelsState==LRWHEELS_STOP)
sepp_nepp 9:efe9f76d6f76 354 { // Turn motor power off!
sepp_nepp 11:5a94af0afa12 355 wheelLeft->MotorOFF();
sepp_nepp 11:5a94af0afa12 356 wheelRight->MotorOFF();
sepp_nepp 9:efe9f76d6f76 357 // Call the externall callback function to inform about the end of all movements
sepp_nepp 9:efe9f76d6f76 358 if(extCallBack!=NULL) extCallBack( wheelsState );
sepp_nepp 9:efe9f76d6f76 359 } // if wheelsState==LRWHEELS_STOP
sepp_nepp 9:efe9f76d6f76 360 } // if ( !qBlock )
sepp_nepp 9:efe9f76d6f76 361 else qCollide = true; // Remember the collision to execute the next command.
sepp_nepp 6:4d8938b686a6 362 }
sepp_nepp 6:4d8938b686a6 363
sepp_nepp 7:3a793ddc3490 364
sepp_nepp 7:3a793ddc3490 365