My Version of CreaBotLib
Fork of CreaBotLib by
CreaBot.h@12:530772639065, 2019-04-18 (annotated)
- 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?
User | Revision | Line number | New contents of line |
---|---|---|---|
sepp_nepp | 7:3a793ddc3490 | 1 | /* |
sepp_nepp | 8:3b5b0a82b429 | 2 | * \file CreaBot.h |
sepp_nepp | 8:3b5b0a82b429 | 3 | * \brief File contains Creabot Library. |
sepp_nepp | 6:4d8938b686a6 | 4 | |
sepp_nepp | 9:efe9f76d6f76 | 5 | * CreaBot.h contains the Creabot class, and required enums and structs. |
sepp_nepp | 11:5a94af0afa12 | 6 | * Imports "mbed.h" and "CreaMot.h" |
sepp_nepp | 6:4d8938b686a6 | 7 | |
sepp_nepp | 6:4d8938b686a6 | 8 | * Refactorings: |
sepp_nepp | 9:efe9f76d6f76 | 9 | * All variables with suffixes "_cm_sec" = speeds in centimeters per second. |
sepp_nepp | 9:efe9f76d6f76 | 10 | * MotCommand -> BotCommand. |
sepp_nepp | 9:efe9f76d6f76 | 11 | * cmdbot_t -> BotCmdVerb. |
sepp_nepp | 9:efe9f76d6f76 | 12 | * cm -> dist_cm. |
sepp_nepp | 9:efe9f76d6f76 | 13 | * 'motorxx' -> 'wheelxxx': each motor now becomes a 'wheel with a diameter' |
sepp_nepp | 9:efe9f76d6f76 | 14 | * FIFO queue management merged with Creabot Class, now called Queue |
sepp_nepp | 9:efe9f76d6f76 | 15 | * Queue does not use another extra ticker anymore. Instead triggers from Motor End commands. |
sepp_nepp | 10:79509113310a | 16 | * Queue is worked through, and Callback is not called, until queue is empty. |
sepp_nepp | 9:efe9f76d6f76 | 17 | * |
sepp_nepp | 10:79509113310a | 18 | * @author Tarek Lule based on work of Francois Druilhe, et al. |
sepp_nepp | 10:79509113310a | 19 | * @date 21. April 2019 |
sepp_nepp | 8:3b5b0a82b429 | 20 | * @see https://os.mbed.com/users/sepp_nepp/code/CreaBotLib/ */ |
sepp_nepp | 6:4d8938b686a6 | 21 | |
sepp_nepp | 9:efe9f76d6f76 | 22 | // -------------------- wheel --------------------------- |
sepp_nepp | 6:4d8938b686a6 | 23 | |
garphil | 0:a7fb03c9ea9d | 24 | #ifndef CREABOT_H |
garphil | 0:a7fb03c9ea9d | 25 | #define CREABOT_H |
garphil | 0:a7fb03c9ea9d | 26 | |
garphil | 0:a7fb03c9ea9d | 27 | #include "mbed.h" |
sepp_nepp | 11:5a94af0afa12 | 28 | #include "CreaMot.h" |
garphil | 0:a7fb03c9ea9d | 29 | |
sepp_nepp | 8:3b5b0a82b429 | 30 | #define DEFAULT_SPEED_CM_SEC 2.0f /**< Default advancement speed = 2.0cm/sec, was DEFAULT_SPEED */ |
sepp_nepp | 9:efe9f76d6f76 | 31 | #define DEPTH_Queue 256 /**< Initialize the depth of the command Queue to 256 */ |
garphil | 0:a7fb03c9ea9d | 32 | |
sepp_nepp | 8:3b5b0a82b429 | 33 | /** \enum BotCmdVerb |
sepp_nepp | 8:3b5b0a82b429 | 34 | * \brief Robot Commands Verbs, gives the movement direction |
sepp_nepp | 12:530772639065 | 35 | * IDLE is no longer supported */ |
sepp_nepp | 6:4d8938b686a6 | 36 | typedef enum { |
sepp_nepp | 9:efe9f76d6f76 | 37 | FORWARD, /**< Advance the robot straight forward */ |
sepp_nepp | 9:efe9f76d6f76 | 38 | BACKWARD, /**< Reverse the robot straight backwards */ |
sepp_nepp | 9:efe9f76d6f76 | 39 | ROTATE, /**< Rotate around its own axis*/ |
sepp_nepp | 9:efe9f76d6f76 | 40 | LEFT, /**< Advance in a left curve */ |
sepp_nepp | 9:efe9f76d6f76 | 41 | RIGHT, /**< Advance in a right curve */ |
sepp_nepp | 9:efe9f76d6f76 | 42 | BACKLEFT, /**< Reverse in a left curve */ |
sepp_nepp | 9:efe9f76d6f76 | 43 | BACKRIGHT /**< Reverse in a right curve */ |
sepp_nepp | 6:4d8938b686a6 | 44 | } BotCmdVerb; |
sepp_nepp | 6:4d8938b686a6 | 45 | |
sepp_nepp | 5:efe80c5db389 | 46 | |
sepp_nepp | 9:efe9f76d6f76 | 47 | /** \enum TWheelsState |
sepp_nepp | 10:79509113310a | 48 | * \brief Possible states of the two wheels of the CreaBot |
sepp_nepp | 10:79509113310a | 49 | * Can be ored together */ |
sepp_nepp | 6:4d8938b686a6 | 50 | typedef enum { |
sepp_nepp | 9:efe9f76d6f76 | 51 | LRWHEELS_STOP = 0, /**< All wheels have stopped */ |
sepp_nepp | 9:efe9f76d6f76 | 52 | LWHEEL_RUNS = 1, /**< Left wheel runs */ |
sepp_nepp | 10:79509113310a | 53 | RWHEEL_RUNS = 2, /**< Right wheel runs */ |
sepp_nepp | 9:efe9f76d6f76 | 54 | LRWHEELS_RUN = 3, /**< Both wheels run */ |
sepp_nepp | 9:efe9f76d6f76 | 55 | } TWheelsState; |
sepp_nepp | 6:4d8938b686a6 | 56 | |
sepp_nepp | 8:3b5b0a82b429 | 57 | /** \struct BotCommand |
sepp_nepp | 10:79509113310a | 58 | * \brief Structure of a CreaBot Command. |
sepp_nepp | 9:efe9f76d6f76 | 59 | * The command structure is put into command Queue, and treated by the Queue-Handler */ |
sepp_nepp | 6:4d8938b686a6 | 60 | typedef struct { |
sepp_nepp | 10:79509113310a | 61 | BotCmdVerb command; /**< Command type that gives movement direction.*/ |
sepp_nepp | 8:3b5b0a82b429 | 62 | float dist_cm; /**< Distance in dist_cm for translational movements .*/ |
sepp_nepp | 9:efe9f76d6f76 | 63 | float turn_angle_deg; /**< Angle in degree for rotational movement .*/ |
sepp_nepp | 9:efe9f76d6f76 | 64 | void set(BotCmdVerb Acommand, float Aturn_angle_deg, float Adist_cm); /**< Helper; set structure fields to values */ |
sepp_nepp | 8:3b5b0a82b429 | 65 | void set(BotCmdVerb Acommand, float Aparam); /**< Helper; set structure fields to values */ |
sepp_nepp | 6:4d8938b686a6 | 66 | } BotCommand; |
sepp_nepp | 6:4d8938b686a6 | 67 | |
garphil | 0:a7fb03c9ea9d | 68 | |
sepp_nepp | 8:3b5b0a82b429 | 69 | /** \class Creabot |
garphil | 0:a7fb03c9ea9d | 70 | |
sepp_nepp | 9:efe9f76d6f76 | 71 | * \brief Synchronous Control of 2 wheels as part of a two wheel robot |
sepp_nepp | 9:efe9f76d6f76 | 72 | * |
sepp_nepp | 10:79509113310a | 73 | * Handles two instances of CreaMot from motor.h library simultaneously. |
sepp_nepp | 9:efe9f76d6f76 | 74 | * Using the set distance between the wheels, allows to run pecise curves. |
sepp_nepp | 12:530772639065 | 75 | * |
sepp_nepp | 12:530772639065 | 76 | * A first set of movement functions starting with qXXX are using command verbs, |
sepp_nepp | 10:79509113310a | 77 | * these commands are queued up in a waiting queue, |
sepp_nepp | 10:79509113310a | 78 | * and are executed one by one in programmed order. |
sepp_nepp | 12:530772639065 | 79 | * |
sepp_nepp | 10:79509113310a | 80 | * A second set of movement functions starting with iXXX are also using command verbs, |
sepp_nepp | 10:79509113310a | 81 | * however these commands are executed immediately, |
sepp_nepp | 10:79509113310a | 82 | * they override each other if issued while the previous movement still ongoing |
sepp_nepp | 12:530772639065 | 83 | * |
sepp_nepp | 10:79509113310a | 84 | * A third set of movements functions starting with moveXXXX are provided, |
sepp_nepp | 10:79509113310a | 85 | * each function performs one specific movement, also immediately. |
sepp_nepp | 10:79509113310a | 86 | * So they also override each other, and collide with queued commands. |
sepp_nepp | 12:530772639065 | 87 | * |
sepp_nepp | 9:efe9f76d6f76 | 88 | * A callback is supplied to react to the end of all programmed movements. |
sepp_nepp | 9:efe9f76d6f76 | 89 | * |
sepp_nepp | 9:efe9f76d6f76 | 90 | * Example: |
sepp_nepp | 9:efe9f76d6f76 | 91 | * @code |
sepp_nepp | 9:efe9f76d6f76 | 92 | * // --- Define the Four PINs & Time of movement used for wheel drive ----- |
sepp_nepp | 10:79509113310a | 93 | * CreaMot wheelLeft(PA_12, PB_0, PB_1, PB_6); // Declare first the 2 wheels (to avoid to have an object with 8 pins to create) |
sepp_nepp | 10:79509113310a | 94 | * CreaMot wheelRight(PA_5,PA_4,PA_3,PA_1); |
sepp_nepp | 12:530772639065 | 95 | * CreaBot mybot(&wheelLeft, &WheelRight, 10.0f, 13.0f); // insert the wheels and indicate wheel diameter (10cm) and distance between wheels (13cm) |
sepp_nepp | 9:efe9f76d6f76 | 96 | * |
sepp_nepp | 9:efe9f76d6f76 | 97 | * int main() { |
sepp_nepp | 9:efe9f76d6f76 | 98 | * |
sepp_nepp | 9:efe9f76d6f76 | 99 | * mybot.setSpeed(12.5); // Preset speed to 12.5cm/s |
sepp_nepp | 9:efe9f76d6f76 | 100 | * mybot.iMove(FORWARD,10); // Go forward of 10cm |
sepp_nepp | 9:efe9f76d6f76 | 101 | * mybot.iWaitEnd(); // Wait end of Move |
sepp_nepp | 9:efe9f76d6f76 | 102 | * mybot.iMove(ROTATE,90); // Start rotation of 90° around the center between wheels (two wheels running in same direction at same speed) |
sepp_nepp | 9:efe9f76d6f76 | 103 | * mybot.iMove(BACKWARD,40); // Stop immediately the rotation and go backward of 40cm |
sepp_nepp | 9:efe9f76d6f76 | 104 | * mybot.iWaitEnd(); // Wait end of Backward |
sepp_nepp | 9:efe9f76d6f76 | 105 | * mybot.iMoveAndWait(LEFT,60); // Move Left of 60° in circle, center being the left wheel (off). Wait end of move |
sepp_nepp | 9:efe9f76d6f76 | 106 | * mybot.iWaitEnd(); // Not needed, as already waited... |
sepp_nepp | 9:efe9f76d6f76 | 107 | * mybot.iMoveAndWait(RIGHT,45, 33); // Move Right of 45°, center being at 33cm of the right wheel. Right wheel moving slower and on a shorter distance than left one. |
sepp_nepp | 9:efe9f76d6f76 | 108 | * mybot.iMoveAndWait(ROTATE,90); |
sepp_nepp | 9:efe9f76d6f76 | 109 | * mybot.iMove(ROTATE,-90); // Opposite direction. |
sepp_nepp | 9:efe9f76d6f76 | 110 | * mybot.iWaitEnd(6); // with time-out => if after 6s the move is not ended, continue the execution |
sepp_nepp | 9:efe9f76d6f76 | 111 | * mybot.iStop(); // Stop the movement in case it was not ended before ... |
sepp_nepp | 9:efe9f76d6f76 | 112 | * |
sepp_nepp | 9:efe9f76d6f76 | 113 | * // Same with a Queue of command, opposite to the move, receiving a new command will not stop the current execution, but the bot will store it. |
sepp_nepp | 9:efe9f76d6f76 | 114 | * mybot.qMove(FORWARD,10); // Already starting... |
sepp_nepp | 9:efe9f76d6f76 | 115 | * mybot.qMove(BACKWARD,10); // will wait end of previous command to go |
sepp_nepp | 9:efe9f76d6f76 | 116 | * mybot.qMove(ROTATE,120.0); |
sepp_nepp | 9:efe9f76d6f76 | 117 | * mybot.qMove(LEFT, 30, 120); |
sepp_nepp | 9:efe9f76d6f76 | 118 | * mybot.qMove(RIGHT, 25); |
sepp_nepp | 9:efe9f76d6f76 | 119 | * ... // insert other code here that executes while the motors continue to move |
sepp_nepp | 9:efe9f76d6f76 | 120 | * mybot.iWaitEnd(100000); // wait until Queue end... can flush anytime with stopMove... |
sepp_nepp | 9:efe9f76d6f76 | 121 | * mybot.qEmpty(); // before end... Flush the Queue and remove all instructions… |
sepp_nepp | 9:efe9f76d6f76 | 122 | * |
sepp_nepp | 9:efe9f76d6f76 | 123 | * while(1) { |
sepp_nepp | 9:efe9f76d6f76 | 124 | * }; |
sepp_nepp | 9:efe9f76d6f76 | 125 | * } |
sepp_nepp | 9:efe9f76d6f76 | 126 | * @endcode |
sepp_nepp | 9:efe9f76d6f76 | 127 | */ |
sepp_nepp | 5:efe80c5db389 | 128 | |
garphil | 0:a7fb03c9ea9d | 129 | class Creabot { |
garphil | 0:a7fb03c9ea9d | 130 | public: |
sepp_nepp | 9:efe9f76d6f76 | 131 | /** Create a Creabot object with 2 wheels |
garphil | 0:a7fb03c9ea9d | 132 | * |
sepp_nepp | 12:530772639065 | 133 | * @param[in] <left> CreaMot object, corresponding to left wheel of the Creabot |
sepp_nepp | 12:530772639065 | 134 | * @param[in] <right> CreaMot object, corresponding to right wheel of the Creabot |
sepp_nepp | 12:530772639065 | 135 | * @param[in] <wheel_diam_cm> Diameter in cm of the wheels (both must be the same diameter) |
sepp_nepp | 12:530772639065 | 136 | * @param[in] <bot_diam_cm> Distance cm between center of left wheel and center of right wheel |
garphil | 0:a7fb03c9ea9d | 137 | */ |
sepp_nepp | 10:79509113310a | 138 | Creabot(CreaMot *left, CreaMot *right, float wheel_diam_cm, float bot_diam_cm); |
sepp_nepp | 6:4d8938b686a6 | 139 | |
sepp_nepp | 9:efe9f76d6f76 | 140 | /** Property access to wheel state, indicating which of the wheels are moving */ |
sepp_nepp | 9:efe9f76d6f76 | 141 | TWheelsState getState() {return wheelsState; }; |
garphil | 0:a7fb03c9ea9d | 142 | |
sepp_nepp | 9:efe9f76d6f76 | 143 | /** Setup a Callback method. It is called when all programmed movements are finished. */ |
sepp_nepp | 10:79509113310a | 144 | void setCallBack(void (*Acallback)(int status)) { extCallBack = Acallback; }; |
sepp_nepp | 9:efe9f76d6f76 | 145 | |
sepp_nepp | 9:efe9f76d6f76 | 146 | /** High level: set bot-speed parameter for all future wheel commands. |
sepp_nepp | 10:79509113310a | 147 | * The set speed is used for immediate as well as the queued movements. |
sepp_nepp | 12:530772639065 | 148 | * In a curve movement it determines the speed of the outer wheel. |
sepp_nepp | 12:530772639065 | 149 | * |
sepp_nepp | 12:530772639065 | 150 | * @param[in] <AbotSpeed_cm_sec> requested movement speed */ |
sepp_nepp | 9:efe9f76d6f76 | 151 | void setSpeed(float AbotSpeed_cm_sec); |
sepp_nepp | 7:3a793ddc3490 | 152 | |
sepp_nepp | 7:3a793ddc3490 | 153 | public: |
sepp_nepp | 9:efe9f76d6f76 | 154 | |
sepp_nepp | 10:79509113310a | 155 | /** High level, queued: move bot according to command and parameter |
sepp_nepp | 12:530772639065 | 156 | * |
sepp_nepp | 9:efe9f76d6f76 | 157 | * Composes a BotCommand and appends it to the queue for queued execution. |
sepp_nepp | 9:efe9f76d6f76 | 158 | * Use for commands that need only one parameter: FORWARD, BACKWARD, ROTATE |
sepp_nepp | 9:efe9f76d6f76 | 159 | * For details refer to docu of moveForward(), moveBackward(), moveRotate(). |
sepp_nepp | 12:530772639065 | 160 | * Preset the speed using setSpeed(). |
sepp_nepp | 10:79509113310a | 161 | * |
sepp_nepp | 9:efe9f76d6f76 | 162 | * @param[in] <Acommand> Requested movement, of type BotCmdVerb. |
sepp_nepp | 9:efe9f76d6f76 | 163 | * @param[in] <Aparam> Requested amount, defines angle for ROTATE, or distance for FORWARD, BACKWARD. |
sepp_nepp | 9:efe9f76d6f76 | 164 | */ |
sepp_nepp | 9:efe9f76d6f76 | 165 | void qMove(BotCmdVerb Acommand, float Aparam); |
sepp_nepp | 9:efe9f76d6f76 | 166 | |
sepp_nepp | 9:efe9f76d6f76 | 167 | /** High level, queued : move bot according to command and parameters |
sepp_nepp | 12:530772639065 | 168 | * |
sepp_nepp | 9:efe9f76d6f76 | 169 | * Composes a BotCommand and appends it to the queue for queued execution. |
sepp_nepp | 9:efe9f76d6f76 | 170 | * Use for commands that need two parameters: LEFT, RIGHT, BACKLEFT, BACKRIGHT |
sepp_nepp | 10:79509113310a | 171 | * For details refer to docu of moveLeft(), moveRight(), moveBackLeft(), moveBackRight(). |
sepp_nepp | 9:efe9f76d6f76 | 172 | * |
sepp_nepp | 10:79509113310a | 173 | * Reserves a new command element at the head of the Queue |
sepp_nepp | 9:efe9f76d6f76 | 174 | * |
sepp_nepp | 9:efe9f76d6f76 | 175 | * Adds incoming commands at the head of the ring buffer at position writeIdx, |
sepp_nepp | 9:efe9f76d6f76 | 176 | * If Queue is full, it passes back NULL |
sepp_nepp | 9:efe9f76d6f76 | 177 | * Otherwise Advances the write index once and returns a pointer the next free command struct. |
sepp_nepp | 9:efe9f76d6f76 | 178 | * The caller then must fill the command structure at that position. |
sepp_nepp | 9:efe9f76d6f76 | 179 | * Do not free memory associated to the pointer. |
sepp_nepp | 9:efe9f76d6f76 | 180 | * |
sepp_nepp | 9:efe9f76d6f76 | 181 | * @param[in] <Acommand> Requested movement, of type BotCmdVerb. |
sepp_nepp | 9:efe9f76d6f76 | 182 | * @param[in] <Aturn_angle_deg> Requested angle in degrees. |
sepp_nepp | 9:efe9f76d6f76 | 183 | * @param[in] <Adist_cm> Requested distance in centimeters. |
sepp_nepp | 9:efe9f76d6f76 | 184 | */ |
sepp_nepp | 9:efe9f76d6f76 | 185 | void qMove(BotCmdVerb Acommand, float Aturn_angle_deg, float Adist_cm); |
sepp_nepp | 9:efe9f76d6f76 | 186 | |
sepp_nepp | 9:efe9f76d6f76 | 187 | /** Execute and remove the oldest element at the tail of the Queue |
sepp_nepp | 9:efe9f76d6f76 | 188 | * |
sepp_nepp | 9:efe9f76d6f76 | 189 | * If Queue is empty, nothing happens |
sepp_nepp | 9:efe9f76d6f76 | 190 | * Otherwise executes oldest commands from the tail of the ring buffer at position readIdx, |
sepp_nepp | 10:79509113310a | 191 | * Then advances the read index once. */ |
sepp_nepp | 9:efe9f76d6f76 | 192 | void qExecuteNext(); |
sepp_nepp | 9:efe9f76d6f76 | 193 | |
sepp_nepp | 9:efe9f76d6f76 | 194 | /** Public access of Queue used Count. |
sepp_nepp | 9:efe9f76d6f76 | 195 | * |
sepp_nepp | 9:efe9f76d6f76 | 196 | * @return <int> the number of commands in the Queue */ |
sepp_nepp | 9:efe9f76d6f76 | 197 | int qCount() {return Count;} |
sepp_nepp | 8:3b5b0a82b429 | 198 | |
sepp_nepp | 9:efe9f76d6f76 | 199 | /* Immediately end all queue activites, and the motor |
sepp_nepp | 9:efe9f76d6f76 | 200 | * Does not call the external callback handler */ |
sepp_nepp | 9:efe9f76d6f76 | 201 | void qStopAll(); |
sepp_nepp | 9:efe9f76d6f76 | 202 | |
sepp_nepp | 9:efe9f76d6f76 | 203 | private: |
sepp_nepp | 9:efe9f76d6f76 | 204 | /** Empty the Queue. |
sepp_nepp | 10:79509113310a | 205 | * Since the ring buffer is static, it suffice to set all pointers to 0, |
sepp_nepp | 10:79509113310a | 206 | * Commands are left in memory. */ |
sepp_nepp | 9:efe9f76d6f76 | 207 | void qReset() { qBlock = true; readIdx=writeIdx=Count=0; qBlock = false; qCollide = false;}; |
sepp_nepp | 9:efe9f76d6f76 | 208 | |
sepp_nepp | 10:79509113310a | 209 | /** Check if Queue is full. |
sepp_nepp | 9:efe9f76d6f76 | 210 | * |
sepp_nepp | 9:efe9f76d6f76 | 211 | * Space is limited to DEPTH_Queue=256 BotCommand elements. |
sepp_nepp | 10:79509113310a | 212 | * If in doubt it should be checked before trying to add new elements |
sepp_nepp | 9:efe9f76d6f76 | 213 | * @return <bool> True if Queue is full*/ |
sepp_nepp | 9:efe9f76d6f76 | 214 | bool qIsFull() {return Count>=DEPTH_Queue;} |
sepp_nepp | 9:efe9f76d6f76 | 215 | |
sepp_nepp | 10:79509113310a | 216 | /** Check if Queue is empty. |
sepp_nepp | 10:79509113310a | 217 | * |
sepp_nepp | 9:efe9f76d6f76 | 218 | * Should be checked before trying to get new elements |
sepp_nepp | 9:efe9f76d6f76 | 219 | * @return <bool> True if Queue is empty*/ |
sepp_nepp | 9:efe9f76d6f76 | 220 | bool qIsEmpty() {return Count<=0;} |
sepp_nepp | 9:efe9f76d6f76 | 221 | |
sepp_nepp | 9:efe9f76d6f76 | 222 | /** 256 elements deep Command Queue, to put BotCommand in a queue. |
sepp_nepp | 9:efe9f76d6f76 | 223 | * Stores all BotCommand in this static 256 array used as a circular ring buffer. */ |
sepp_nepp | 9:efe9f76d6f76 | 224 | BotCommand cmd[DEPTH_Queue]; /**< Actual static Queue array where all elements reside. */ |
sepp_nepp | 9:efe9f76d6f76 | 225 | |
sepp_nepp | 9:efe9f76d6f76 | 226 | int writeIdx; /**< Index in Queue array where to put the next new element to. */ |
sepp_nepp | 9:efe9f76d6f76 | 227 | int readIdx; /**< Index in Queue array where to get the oldest element from. */ |
sepp_nepp | 9:efe9f76d6f76 | 228 | int Count; /**< Counts and keeps track of the number of elements in array used. */ |
sepp_nepp | 9:efe9f76d6f76 | 229 | bool qBlock; /**< Blocks read access while a write is ongoing. */ |
sepp_nepp | 9:efe9f76d6f76 | 230 | bool qCollide;/**< Indicates a colliding access to the queue. */ |
sepp_nepp | 10:79509113310a | 231 | |
sepp_nepp | 9:efe9f76d6f76 | 232 | public: |
sepp_nepp | 9:efe9f76d6f76 | 233 | /** High level, immediate: move bot and wait for movement end. |
sepp_nepp | 12:530772639065 | 234 | * Simple wrapper for iMove() and iWaitEnd(). |
sepp_nepp | 9:efe9f76d6f76 | 235 | * Refer to those methods for further docs. |
sepp_nepp | 9:efe9f76d6f76 | 236 | */ |
sepp_nepp | 9:efe9f76d6f76 | 237 | void iMoveAndWait(BotCmdVerb Acommand, float Aparam); |
sepp_nepp | 9:efe9f76d6f76 | 238 | |
sepp_nepp | 9:efe9f76d6f76 | 239 | /** High level, immediate: move bot and wait for movement end. |
sepp_nepp | 12:530772639065 | 240 | * Simple wrapper for iMove() and iWaitEnd(). |
sepp_nepp | 9:efe9f76d6f76 | 241 | * Refer to those methods for further docs. |
sepp_nepp | 9:efe9f76d6f76 | 242 | */ |
sepp_nepp | 9:efe9f76d6f76 | 243 | void iMoveAndWait(BotCmdVerb Acommand, float Aturn_angle_deg, float Adist_cm); |
sepp_nepp | 9:efe9f76d6f76 | 244 | |
sepp_nepp | 9:efe9f76d6f76 | 245 | /** High level, immediate: move bot according to command and parameter |
sepp_nepp | 9:efe9f76d6f76 | 246 | * Composes a BotCommand and passes it to executeCommand(). |
sepp_nepp | 8:3b5b0a82b429 | 247 | * Use for commands that need only one parameter: FORWARD, BACKWARD, ROTATE |
sepp_nepp | 9:efe9f76d6f76 | 248 | * For details refer to docu of moveForward(), moveBackward(), moveRotate(). |
sepp_nepp | 9:efe9f76d6f76 | 249 | * Preset the speed using setSpeed(). |
sepp_nepp | 8:3b5b0a82b429 | 250 | * Warning: Collides with queued commands. |
sepp_nepp | 10:79509113310a | 251 | * |
sepp_nepp | 9:efe9f76d6f76 | 252 | * @param[in] <Acommand> Requested movement, of type BotCmdVerb. |
sepp_nepp | 9:efe9f76d6f76 | 253 | * @param[in] <Aparam> Requested amount, defines angle for ROTATE, or distance for FORWARD, BACKWARD. |
sepp_nepp | 9:efe9f76d6f76 | 254 | */ |
sepp_nepp | 9:efe9f76d6f76 | 255 | void iMove(BotCmdVerb Acommand, float Aparam); |
sepp_nepp | 9:efe9f76d6f76 | 256 | |
sepp_nepp | 9:efe9f76d6f76 | 257 | /** High level, immediate: move bot according to command and parameters |
sepp_nepp | 9:efe9f76d6f76 | 258 | * Composes a BotCommand and passes it to executeCommand(). |
sepp_nepp | 9:efe9f76d6f76 | 259 | * Use for commands that need two parameters: LEFT, RIGHT, BACKLEFT, BACKRIGHT |
sepp_nepp | 10:79509113310a | 260 | * For details refer to docu of moveLeft(), moveRight(), moveBackLeft(), moveBackRight(). |
sepp_nepp | 9:efe9f76d6f76 | 261 | * Preset the speed using setSpeed(). |
sepp_nepp | 9:efe9f76d6f76 | 262 | * Warning: Collides with queued commands. |
sepp_nepp | 10:79509113310a | 263 | * |
sepp_nepp | 9:efe9f76d6f76 | 264 | * @param[in] <Acommand> Requested movement, of type BotCmdVerb. |
sepp_nepp | 9:efe9f76d6f76 | 265 | * @param[in] <Aturn_angle_deg> Requested angle in degrees. |
sepp_nepp | 9:efe9f76d6f76 | 266 | * @param[in] <Adist_cm> Requested distance in centimeters. |
sepp_nepp | 8:3b5b0a82b429 | 267 | */ |
sepp_nepp | 9:efe9f76d6f76 | 268 | void iMove(BotCmdVerb Acommand, float Aturn_angle_deg, float Adist_cm); |
sepp_nepp | 9:efe9f76d6f76 | 269 | |
sepp_nepp | 9:efe9f76d6f76 | 270 | /** High level, immediate: move bot according to prefilled command structures. |
sepp_nepp | 10:79509113310a | 271 | * Recommended to use iMove() methods to fill the command structure correctly. |
sepp_nepp | 9:efe9f76d6f76 | 272 | * Branches to the moveXXXX() methods. For details see docs for those methods. |
sepp_nepp | 9:efe9f76d6f76 | 273 | * Preset the speed using setSpeed(). |
sepp_nepp | 9:efe9f76d6f76 | 274 | * Warning: Collides with queued commands if called individually. |
sepp_nepp | 10:79509113310a | 275 | * |
sepp_nepp | 9:efe9f76d6f76 | 276 | * @param[in] <*cmd> Pointer to type BotCommand, the prefilled command structure, |
sepp_nepp | 9:efe9f76d6f76 | 277 | */ |
sepp_nepp | 9:efe9f76d6f76 | 278 | void iExeCommand(BotCommand *cmd); |
sepp_nepp | 9:efe9f76d6f76 | 279 | |
sepp_nepp | 9:efe9f76d6f76 | 280 | /** High Level: spends all time with waits, |
sepp_nepp | 9:efe9f76d6f76 | 281 | * returns only once wheelState = LRWHEELS_STOP, |
sepp_nepp | 9:efe9f76d6f76 | 282 | * not recommended due its blocking behavior */ |
sepp_nepp | 9:efe9f76d6f76 | 283 | void iWaitEnd(); |
sepp_nepp | 9:efe9f76d6f76 | 284 | |
sepp_nepp | 9:efe9f76d6f76 | 285 | /** High Level: spends all time with waits, |
sepp_nepp | 9:efe9f76d6f76 | 286 | * returns only once wheelState = LRWHEELS_STOP, |
sepp_nepp | 9:efe9f76d6f76 | 287 | * but waits no more than max_wait_ms milli seconds. |
sepp_nepp | 9:efe9f76d6f76 | 288 | * Not recommended due its blocking behavior */ |
sepp_nepp | 9:efe9f76d6f76 | 289 | void iWaitEnd(uint32_t max_wait_ms); // time-out |
sepp_nepp | 9:efe9f76d6f76 | 290 | |
sepp_nepp | 9:efe9f76d6f76 | 291 | /** High level, immediate: Both wheels get stopped, and turned off |
sepp_nepp | 9:efe9f76d6f76 | 292 | * updates the wheel state wheelsState, does not call the callback handler! |
sepp_nepp | 10:79509113310a | 293 | * It does not empty the queue. |
sepp_nepp | 10:79509113310a | 294 | * Adding new elements into the queue after calling iStop() |
sepp_nepp | 10:79509113310a | 295 | * Would continue using all commands still in the queue. */ |
sepp_nepp | 9:efe9f76d6f76 | 296 | void iStop(); |
garphil | 0:a7fb03c9ea9d | 297 | |
sepp_nepp | 7:3a793ddc3490 | 298 | public: |
sepp_nepp | 5:efe80c5db389 | 299 | |
sepp_nepp | 9:efe9f76d6f76 | 300 | /** Mid level, immediate: advance bot straight forward for a given distance, |
sepp_nepp | 9:efe9f76d6f76 | 301 | * Preset the speed using setSpeed(). |
sepp_nepp | 9:efe9f76d6f76 | 302 | * Warning: Collides with queued commands. |
sepp_nepp | 9:efe9f76d6f76 | 303 | */ |
sepp_nepp | 7:3a793ddc3490 | 304 | void moveForward(float dist_cm); |
sepp_nepp | 8:3b5b0a82b429 | 305 | |
sepp_nepp | 9:efe9f76d6f76 | 306 | /** Mid level, immediate: reverse bot straight backwards for a given distance, |
sepp_nepp | 9:efe9f76d6f76 | 307 | * Preset the speed using setSpeed(). |
sepp_nepp | 9:efe9f76d6f76 | 308 | * Warning: Collides with queued commands. |
sepp_nepp | 9:efe9f76d6f76 | 309 | */ |
sepp_nepp | 7:3a793ddc3490 | 310 | void moveBackward(float dist_cm); |
sepp_nepp | 8:3b5b0a82b429 | 311 | |
sepp_nepp | 8:3b5b0a82b429 | 312 | /* Mid level, immediate: turn bot forward right, |
sepp_nepp | 8:3b5b0a82b429 | 313 | * around a radius twice the bot size , |
sepp_nepp | 9:efe9f76d6f76 | 314 | * Same as moveRight(turn_angle_deg, 0); |
sepp_nepp | 9:efe9f76d6f76 | 315 | * Preset the speed using setSpeed(). |
sepp_nepp | 9:efe9f76d6f76 | 316 | * Warning: Collides with queued commands. |
sepp_nepp | 9:efe9f76d6f76 | 317 | */ |
sepp_nepp | 9:efe9f76d6f76 | 318 | void moveRight(float turn_angle_deg); |
sepp_nepp | 8:3b5b0a82b429 | 319 | |
sepp_nepp | 8:3b5b0a82b429 | 320 | /** Mid level, immediate: turn bot forward right, |
sepp_nepp | 8:3b5b0a82b429 | 321 | * around a radius that is center_cm away from the right wheel, |
sepp_nepp | 9:efe9f76d6f76 | 322 | * Preset the speed using setSpeed(). |
sepp_nepp | 9:efe9f76d6f76 | 323 | * Warning: Collides with queued commands. |
sepp_nepp | 9:efe9f76d6f76 | 324 | */ |
sepp_nepp | 9:efe9f76d6f76 | 325 | void moveRight(float turn_angle_deg, float center_cm); |
sepp_nepp | 8:3b5b0a82b429 | 326 | |
sepp_nepp | 8:3b5b0a82b429 | 327 | /** Mid level, immediate: turn bot forward left, |
sepp_nepp | 8:3b5b0a82b429 | 328 | * around a radius twice the bot size, |
sepp_nepp | 9:efe9f76d6f76 | 329 | * Same as moveLeft(turn_angle_deg, 0); |
sepp_nepp | 9:efe9f76d6f76 | 330 | * Preset the speed using setSpeed(). |
sepp_nepp | 9:efe9f76d6f76 | 331 | * Warning: Collides with queued commands. |
sepp_nepp | 9:efe9f76d6f76 | 332 | */ |
sepp_nepp | 9:efe9f76d6f76 | 333 | void moveLeft(float turn_angle_deg); |
sepp_nepp | 8:3b5b0a82b429 | 334 | |
sepp_nepp | 8:3b5b0a82b429 | 335 | /** Mid level, immediate: turn bot forward left, |
sepp_nepp | 9:efe9f76d6f76 | 336 | * around a radius that is center_cm away from the left wheel, |
sepp_nepp | 9:efe9f76d6f76 | 337 | * Preset the speed using setSpeed(). |
sepp_nepp | 9:efe9f76d6f76 | 338 | * Warning: Collides with queued commands. |
sepp_nepp | 9:efe9f76d6f76 | 339 | */ |
sepp_nepp | 9:efe9f76d6f76 | 340 | void moveLeft(float turn_angle_deg, float center_cm); |
sepp_nepp | 9:efe9f76d6f76 | 341 | |
sepp_nepp | 9:efe9f76d6f76 | 342 | /* Mid level, immediate: turn bot backwards right, |
sepp_nepp | 9:efe9f76d6f76 | 343 | * around a radius twice the bot size , |
sepp_nepp | 10:79509113310a | 344 | * Same as moveBackRight(turn_angle_deg, 0); |
sepp_nepp | 9:efe9f76d6f76 | 345 | * Preset the speed using setSpeed(). |
sepp_nepp | 9:efe9f76d6f76 | 346 | * Warning: Collides with queued commands. |
sepp_nepp | 9:efe9f76d6f76 | 347 | */ |
sepp_nepp | 10:79509113310a | 348 | void moveBackRight(float turn_angle_deg); |
sepp_nepp | 9:efe9f76d6f76 | 349 | |
sepp_nepp | 9:efe9f76d6f76 | 350 | /** Mid level, immediate: turn bot backwards right, |
sepp_nepp | 9:efe9f76d6f76 | 351 | * around a radius that is center_cm away from the right wheel, |
sepp_nepp | 9:efe9f76d6f76 | 352 | * Preset the speed using setSpeed(). |
sepp_nepp | 9:efe9f76d6f76 | 353 | * Warning: Collides with queued commands. |
sepp_nepp | 9:efe9f76d6f76 | 354 | */ |
sepp_nepp | 10:79509113310a | 355 | void moveBackRight(float turn_angle_deg, float center_cm); |
sepp_nepp | 9:efe9f76d6f76 | 356 | |
sepp_nepp | 9:efe9f76d6f76 | 357 | /** Mid level, immediate: turn bot backwards left, |
sepp_nepp | 9:efe9f76d6f76 | 358 | * around a radius twice the bot size, |
sepp_nepp | 10:79509113310a | 359 | * Same as moveBackLeft(turn_angle_deg, 0); |
sepp_nepp | 9:efe9f76d6f76 | 360 | * Preset the speed using setSpeed(). |
sepp_nepp | 9:efe9f76d6f76 | 361 | * Warning: Collides with queued commands. |
sepp_nepp | 9:efe9f76d6f76 | 362 | */ |
sepp_nepp | 10:79509113310a | 363 | void moveBackLeft(float turn_angle_deg); |
sepp_nepp | 9:efe9f76d6f76 | 364 | |
sepp_nepp | 9:efe9f76d6f76 | 365 | /** Mid level, immediate: turn bot backwards left, |
sepp_nepp | 8:3b5b0a82b429 | 366 | around a radius that is center_cm away from the left wheel, |
sepp_nepp | 9:efe9f76d6f76 | 367 | * Preset the speed using setSpeed(). |
sepp_nepp | 9:efe9f76d6f76 | 368 | * Warning: Collides with queued commands. |
sepp_nepp | 9:efe9f76d6f76 | 369 | */ |
sepp_nepp | 10:79509113310a | 370 | void moveBackLeft(float turn_angle_deg, float center_cm); |
sepp_nepp | 9:efe9f76d6f76 | 371 | |
sepp_nepp | 8:3b5b0a82b429 | 372 | /** Mid level, immediate: turn bot on its place for a given angle. |
sepp_nepp | 8:3b5b0a82b429 | 373 | * positive angles turn right, negative angles turn left, |
sepp_nepp | 9:efe9f76d6f76 | 374 | * Preset the speed using setSpeed(). |
sepp_nepp | 9:efe9f76d6f76 | 375 | * Warning: Collides with queued commands. |
sepp_nepp | 9:efe9f76d6f76 | 376 | */ |
sepp_nepp | 9:efe9f76d6f76 | 377 | void moveRotate(float turn_angle_deg); |
sepp_nepp | 7:3a793ddc3490 | 378 | |
sepp_nepp | 6:4d8938b686a6 | 379 | private: |
sepp_nepp | 7:3a793ddc3490 | 380 | |
sepp_nepp | 9:efe9f76d6f76 | 381 | /** Low level, immediate: sets Both wheel speeds */ |
sepp_nepp | 9:efe9f76d6f76 | 382 | void wheelsSetSpeed(float mot_speed_cm_sec); |
sepp_nepp | 8:3b5b0a82b429 | 383 | |
sepp_nepp | 9:efe9f76d6f76 | 384 | /** Callback when left wheel stops; |
sepp_nepp | 9:efe9f76d6f76 | 385 | * updates the wheel state wheelsState */ |
sepp_nepp | 9:efe9f76d6f76 | 386 | void wheelLeftStoppedCB(); |
sepp_nepp | 8:3b5b0a82b429 | 387 | |
sepp_nepp | 9:efe9f76d6f76 | 388 | /** Callback when right wheel stops. |
sepp_nepp | 9:efe9f76d6f76 | 389 | * updates the wheel state wheelsState */ |
sepp_nepp | 9:efe9f76d6f76 | 390 | void wheelRightStoppedCB(); |
sepp_nepp | 8:3b5b0a82b429 | 391 | |
sepp_nepp | 9:efe9f76d6f76 | 392 | /** Callback when all wheels have stopped. |
sepp_nepp | 9:efe9f76d6f76 | 393 | * updates the wheel state wheelsState, switch off all Phases */ |
sepp_nepp | 9:efe9f76d6f76 | 394 | void wheelsAllStoppedCB(); |
sepp_nepp | 7:3a793ddc3490 | 395 | |
sepp_nepp | 8:3b5b0a82b429 | 396 | /** Callback function pointer: |
sepp_nepp | 9:efe9f76d6f76 | 397 | * If set non-NULL it is called when All wheels Stopped()*/ |
sepp_nepp | 7:3a793ddc3490 | 398 | void (*extCallBack)(int status); |
sepp_nepp | 7:3a793ddc3490 | 399 | |
sepp_nepp | 9:efe9f76d6f76 | 400 | /** Wheel status register: |
sepp_nepp | 9:efe9f76d6f76 | 401 | * Remembers which of the wheels still run */ |
sepp_nepp | 9:efe9f76d6f76 | 402 | TWheelsState wheelsState; |
sepp_nepp | 7:3a793ddc3490 | 403 | |
sepp_nepp | 9:efe9f76d6f76 | 404 | /** geometric properties of the bot */ |
sepp_nepp | 9:efe9f76d6f76 | 405 | float botDiameter; |
sepp_nepp | 9:efe9f76d6f76 | 406 | |
sepp_nepp | 8:3b5b0a82b429 | 407 | /** Ratio of wheel diameter and bot diameter */ |
sepp_nepp | 8:3b5b0a82b429 | 408 | float ratio_wheel_bot; |
sepp_nepp | 9:efe9f76d6f76 | 409 | |
sepp_nepp | 8:3b5b0a82b429 | 410 | /** last requested bot speed */ |
sepp_nepp | 9:efe9f76d6f76 | 411 | float botSpeed_cm_sec; |
sepp_nepp | 8:3b5b0a82b429 | 412 | |
sepp_nepp | 9:efe9f76d6f76 | 413 | /** The two wheels, as pointers to their classes */ |
sepp_nepp | 10:79509113310a | 414 | CreaMot *wheelLeft; |
sepp_nepp | 10:79509113310a | 415 | CreaMot *wheelRight; |
garphil | 0:a7fb03c9ea9d | 416 | }; |
garphil | 0:a7fb03c9ea9d | 417 | |
sepp_nepp | 9:efe9f76d6f76 | 418 | |
garphil | 0:a7fb03c9ea9d | 419 | #endif |