Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of CreaBotLib by
Diff: CreaBot.cpp
- Revision:
- 5:efe80c5db389
- Parent:
- 4:531b1120d3ec
- Child:
- 6:4d8938b686a6
diff -r 531b1120d3ec -r efe80c5db389 CreaBot.cpp
--- a/CreaBot.cpp Thu Aug 31 08:15:00 2017 +0000
+++ b/CreaBot.cpp Wed Oct 31 14:36:07 2018 +0000
@@ -1,6 +1,52 @@
#include "CreaBot.h"
-Creabot::Creabot(Motor *left, Motor *right, float diameter_wheel_cm, float distance_wheel_cm):motor_left(left), motor_right(right), diameter_wheel(diameter_wheel_cm), distance_wheel(distance_wheel_cm)
+// *****************************************************************
+// Motor Command and Command-FIFO classes
+// *****************************************************************
+
+void MotCommand::assign(cmdbot_t cmd, float p1, float p2)
+{ command = cmd;
+ switch (command) {
+ case FORWARD : ;
+ case BACKWARD: cm=p1; angle=0; break;
+ case ROTATE : angle = p1; break;
+ case LEFT :
+ case RIGHT : angle = p1; cm=p2; break;
+ case IDLE : break;
+ default : break;
+ };
+};
+
+MotCommand *CommandFIFO::put() {
+ if(count<DEPTH_FIFO) {
+ int old_writeIdx = writeIdx;
+ writeIdx++;
+ if (writeIdx==DEPTH_FIFO) writeIdx=0;
+ count++;
+ return &cmd[old_writeIdx];
+ }
+ else
+ return NULL;
+}; // put()
+
+MotCommand *CommandFIFO::get() {
+ if ( !isEmpty() ) {
+ int old_readIdx = readIdx;
+ readIdx++;
+ if (readIdx==DEPTH_FIFO) readIdx=0;
+ count--;
+ return &cmd[old_readIdx];
+ }
+ else
+ return NULL;
+}; // get()
+
+// *****************************************************************
+// Creabot Class
+// *****************************************************************
+
+Creabot::Creabot(Motor *left, Motor *right, float diameter_wheel_cm, float distance_wheel_cm):
+ motor_left(left), motor_right(right), diameter_wheel(diameter_wheel_cm), distance_wheel(distance_wheel_cm)
{
perimeter_wheel = PI*diameter_wheel;
perimeter_bot = PI*distance_wheel;
@@ -9,45 +55,41 @@
ratio_wheel_bot=perimeter_bot/perimeter_wheel;
status=0;
- motor_left->setMotorCallback(this, &Creabot::callBackLeft);
- motor_right->setMotorCallback(this, &Creabot::callBackRight);
+ motor_left->setMotorCallback(this, &Creabot::callBackLeft);
+ motor_right->setMotorCallback(this, &Creabot::callBackRight);
extCallBack = NULL;
setSpeed(DEFAULT_SPEED);
- callLeft = true;
- callRight = true;
+ endMoveLeft = true;
+ endMoveRight = true;
endMove=true;
executingFifo=false;
}
void Creabot::moveForward(float cm)
{
- float angle;
- if(cm<0) moveBackward(cm);
- angle = cm*degree_wheel_per_cm;
- setSpeedLeft(current_speed);
- setSpeedRight(current_speed);
- moveMotorLeft(COUNTERCLOCKWISE, angle);
- moveMotorRight(CLOCKWISE, angle);
-
+ if (cm<0) moveBackward(cm);
+ else {
+ float angle = cm*degree_wheel_per_cm;
+ setSpeed(last_speed);
+ moveMotorLeft(COUNTERCLOCKWISE, angle);
+ moveMotorRight(CLOCKWISE, angle);
+ }
}
void Creabot::moveBackward(float cm)
{
- float angle;
if(cm<0) moveForward(cm);
- angle = cm*degree_wheel_per_cm;
- setSpeedLeft(current_speed);
- setSpeedRight(current_speed);
- moveMotorLeft(CLOCKWISE, angle);
- moveMotorRight(COUNTERCLOCKWISE, angle);
-
+ else {
+ float angle = cm*degree_wheel_per_cm;
+ setSpeed(last_speed);
+ moveMotorLeft(CLOCKWISE, angle);
+ moveMotorRight(COUNTERCLOCKWISE, angle);
+ }
}
void Creabot::rotate(float angleBot)
{
- float angleWheel;
- setSpeedLeft(current_speed);
- setSpeedRight(current_speed);
- angleWheel = angleBot*ratio_wheel_bot;
+ float angleWheel = angleBot*ratio_wheel_bot;
+ setSpeed(last_speed);
if(angleBot<0) {
moveMotorLeft(CLOCKWISE, -angleWheel);
moveMotorRight(CLOCKWISE, -angleWheel);
@@ -56,88 +98,17 @@
moveMotorRight(COUNTERCLOCKWISE, angleWheel);
}
}
-void Creabot::moveRight(float angle)
-{
- moveRight(angle,distance_wheel);
-}
-void Creabot::moveRight(float angle, float center_cm)
-{
- if(center_cm<0) center_cm=0; /* TO remove? */
- float perimeter_outer = 2.0f*angle*(center_cm+distance_wheel)*PI/360.0f;
- float perimeter_inner = 2.0f*angle*(center_cm)*PI/360.0f;
- float angleLeft = perimeter_outer*degree_wheel_per_cm;
- float angleRight = perimeter_inner*degree_wheel_per_cm;
- float ratio = angleRight/angleLeft;
- float speedRight = current_speed * ratio;
- // pc_uart.printf("Set Perimeter angle =%f center_cm=%f outer = %f inner = %f angle_left %f angle right %f ratio %f cs %f\n\r",angle, center_cm, perimeter_outer,perimeter_inner,angleLeft,angleRight,ratio, current_speed);
- setSpeedLeft(current_speed);
- setSpeedRight(speedRight);
- moveMotorLeft(COUNTERCLOCKWISE, angleLeft);
- moveMotorRight(CLOCKWISE, angleRight);
-}
-void Creabot::moveLeft(float angle)
-{
- moveLeft(angle,0);
-}
-void Creabot::moveLeft(float angle, float center_cm)
-{
- if(center_cm<0) center_cm=0; /* TO remove? */
- float perimeter_outer = 2.0f*angle*(center_cm+distance_wheel)*PI/360.0f;
- float perimeter_inner = 2.0f*angle*(center_cm)*PI/360.0f;
- float angleLeft = perimeter_inner*degree_wheel_per_cm;
- float angleRight = perimeter_outer*degree_wheel_per_cm;
- float ratio = angleLeft/angleRight;
- float speedRLeft = current_speed * ratio;
- setSpeedLeft(speedRLeft);
- setSpeedRight(current_speed);
- moveMotorLeft(COUNTERCLOCKWISE, angleLeft);
- moveMotorRight(CLOCKWISE, angleRight);
-
-}
void Creabot::stopMove()
{
- motor_left->Stop();
- motor_right->Stop();
- callLeft = true;
- callRight = true;
+ motor_left->MotorOFF();
+ motor_right->MotorOFF();
+ endMoveLeft = true;
+ endMoveRight = true;
endMove = true;
flushFifo();
// callBack(); // ? To be called or set as parameter?
}
-int Creabot::getStatus()
-{
- if(endMove == true) return 0; // No Movement
- if(callRight == true) return 1; // Left Motor still running
- if(callLeft == true) return 3; // ERROR
- return 2; // Left Motor still running
-}
-
-void Creabot::setSpeed(float cm_per_second)
-{
- setSpeedLeft(cm_per_second);
- setSpeedRight(cm_per_second);
- current_speed = cm_per_second;
-}
-
-uint32_t Creabot::computeSpeed(Motor *motor, float cm_per_second)
-{
- uint32_t tick, timeUnit;
- tick = motor->getCalibration();
- if(cm_per_second <0.0001f) timeUnit = 1000000; else
- timeUnit = perimeter_wheel * 1000000 / cm_per_second / tick;
- return timeUnit;
-}
-
-void Creabot::setSpeedLeft(float cm_per_second)
-{
- motor_left->setDelayBtwTicks(computeSpeed(motor_left, cm_per_second));
-}
-
-void Creabot::setSpeedRight(float cm_per_second)
-{
- motor_right->setDelayBtwTicks(computeSpeed(motor_right, cm_per_second));
-}
void Creabot::waitEndMove()
{
@@ -163,42 +134,32 @@
void Creabot::fifo(cmdbot_t moveType, float angle_or_cm)
{
- CommandBot *cmd = fifoBot.put();
- if(cmd!=NULL) {
- cmd->add_command(moveType, angle_or_cm, 0);
- }
- executeFifo();
-}
-void Creabot::fifo(cmdbot_t moveType, float angle, float cm)
-{
- CommandBot *cmd = fifoBot.put();
- if(cmd!=NULL) {
- cmd->add_command(moveType, angle, cm);
- }
+ MotCommand *cmd = fifoBot.put();
+ if(cmd != NULL) {
+ cmd->assign(moveType, angle_or_cm, 0);
+ }
executeFifo();
}
+void Creabot::fifo(cmdbot_t moveType, float angle, float cm)
+{
+ MotCommand *cmd = fifoBot.put();
+ if(cmd!=NULL) {
+ cmd->assign(moveType, angle, cm);
+ }
+ executeFifo();
+}
void Creabot::moveAndWait(cmdbot_t moveType, float angle_or_cm)
{
- move(moveType,angle_or_cm);
- waitEndMove();
-}
-void Creabot::moveAndWait(cmdbot_t moveType, float angle, float cm)
-{
- move(moveType,angle,cm);
- waitEndMove();
+ move(moveType,angle_or_cm);
+ waitEndMove();
}
-void Creabot::move(cmdbot_t moveType, float angle_or_cm)
+void Creabot::moveAndWait(cmdbot_t moveType, float angle, float cm)
{
- current_cmd.add_command(moveType, angle_or_cm, 0);
- executeCommand(¤t_cmd);
-}
-void Creabot::move(cmdbot_t moveType, float angle, float cm)
-{
- current_cmd.add_command(moveType, angle, cm);
- executeCommand(¤t_cmd);
+ move(moveType,angle,cm);
+ waitEndMove();
}
void Creabot::flushFifo()
@@ -207,11 +168,71 @@
if(executingFifo) botTicker.detach();
executingFifo=false;
}
+
int Creabot::moveInFifo()
{
- return fifoBot.getSize();
+ return fifoBot.getCount();
+}
+
+void Creabot::spirale(float b, float turns) {
+ float r=0.0;
+ float angle = 0.0f;
+ while(angle < float( 360.0 * turns) ) {
+ this->moveAndWait(RIGHT, 10, r);
+ r=r+b;
+ }
+}
+
+void Creabot::callBackLeft()
+{
+ endMoveLeft=true;
+ if(endMoveRight)callBack();
+}
+
+void Creabot::callBackRight()
+{
+ endMoveRight=true;
+ if(endMoveLeft)callBack();
+}
+
+void Creabot::callBack()
+{
+ endMove=true;
+ if(extCallBack!=NULL) extCallBack(status);
}
-void Creabot::executeCommand(CommandBot *cmd) {
+
+
+//******************************************
+// Executing the FIFO of Motor Commands
+//******************************************
+
+// This is the own callback function of the ticker, that works throught the FIFO stack
+void Creabot::executeFifo()
+{ if (fifoBot.isEmpty()) flushFifo();
+ else {
+ if(endMove) {
+ MotCommand *cmd = fifoBot.get();
+ executeCommand(cmd);
+ if (!executingFifo) botTicker.attach_us( callback( this, &Creabot::executeFifo), 3150);
+ executingFifo=true;
+ }
+ }
+}
+
+void Creabot::move(cmdbot_t moveType, float angle_or_cm)
+{
+ current_cmd.assign(moveType, angle_or_cm, 0);
+ executeCommand(¤t_cmd);
+}
+
+void Creabot::move(cmdbot_t moveType, float angle, float cm)
+{
+ current_cmd.assign(moveType, angle, cm);
+ executeCommand(¤t_cmd);
+}
+
+// Direct Command Execution, called by FIFO-Handler.
+void Creabot::executeCommand(MotCommand *cmd) {
switch (cmd->command) {
case FORWARD:
moveForward(cmd->cm);
@@ -234,59 +255,91 @@
default:
break;
};
-}
-void Creabot::executeFifo()
-{
+}; // executeCommand
+
- if(fifoBot.getSize()==0) flushFifo();
- else {
- if(endMove) {
- CommandBot *cmd = fifoBot.get();
- executeCommand(cmd);
- if(!executingFifo) botTicker.attach_us(callback(this,&Creabot::executeFifo),3150);
- executingFifo=true;
+//***********************************************
+// Execute high level motor functions directly, no FIFO
+//***********************************************
- }
- }
+void Creabot::moveRight(float angle)
+{
+ moveRight(angle,distance_wheel);
}
-void Creabot::spirale(float b, float turns) {
- float r=0.0;
- float angle = 0.0f;
- while(angle < 360.0*turns) {
- this->moveAndWait(RIGHT, 10, r);
- r=r+b;
- }
+void Creabot::moveRight(float angle, float center_cm)
+{
+ if(center_cm<0) center_cm=0; /* TO remove? */
+ float perimeter_outer = 2.0f*angle*(center_cm+distance_wheel)*PI/360.0f;
+ float perimeter_inner = 2.0f*angle*(center_cm)*PI/360.0f;
+ float angleLeft = perimeter_outer*degree_wheel_per_cm;
+ float angleRight = perimeter_inner*degree_wheel_per_cm;
+ float ratio = angleRight/angleLeft;
+ float speedRight = last_speed * ratio;
+ // pc_uart.printf("Set Perimeter angle =%f center_cm=%f outer = %f inner = %f angle_left %f angle right %f ratio %f cs %f\n\r",angle, center_cm, perimeter_outer,perimeter_inner,angleLeft,angleRight,ratio, last_speed);
+ setSpeedMot(motor_left,last_speed);
+ setSpeedMot(motor_right,speedRight);
+ moveMotorLeft(COUNTERCLOCKWISE, angleLeft);
+ moveMotorRight(CLOCKWISE, angleRight);
+}
+
+void Creabot::moveLeft(float angle)
+{
+ moveLeft(angle,0);
}
-void Creabot::callBackLeft()
+void Creabot::moveLeft(float angle, float center_cm)
{
- callLeft=true;
- if(callRight)callBack();
-}
-void Creabot::callBackRight()
-{
- callRight=true;
- if(callLeft)callBack();
+ if(center_cm<0) center_cm=0; /* TO remove? */
+ float perimeter_outer = 2.0f*angle*(center_cm+distance_wheel)*PI/360.0f;
+ float perimeter_inner = 2.0f*angle*(center_cm)*PI/360.0f;
+ float angleLeft = perimeter_inner*degree_wheel_per_cm;
+ float angleRight = perimeter_outer*degree_wheel_per_cm;
+ float ratio = angleLeft/angleRight;
+ float speedRLeft = last_speed * ratio;
+ setSpeedMot(motor_left,speedRLeft);
+ setSpeedMot(motor_right,last_speed);
+ moveMotorLeft(COUNTERCLOCKWISE, angleLeft);
+ moveMotorRight(CLOCKWISE, angleRight);
}
-void Creabot::callBack()
-{
- endMove=true;
- if(extCallBack!=NULL) extCallBack(status);
-}
+//******************************************************************************
+// low level motor functions, filters for angle>0, remembers that a motor moves
+//******************************************************************************
-void Creabot::moveMotorLeft(MotorDir dir, float angle)
+void Creabot::moveMotorLeft(motorDir dir, float angle)
{
if(angle>0) {
motor_left->RunDegrees(dir, angle);
- endMove = callLeft = false;
+ endMove = endMoveLeft = false;
}
}
-void Creabot::moveMotorRight(MotorDir dir, float angle)
-{
- if(angle>0) {
+
+void Creabot::moveMotorRight(motorDir dir, float angle)
+{ if(angle>0) {
motor_right->RunDegrees(dir, angle);
- endMove = callRight = false;
- }
-}
\ No newline at end of file
+ endMove = endMoveRight = false;}
+}
+
+int Creabot::getStatus()
+{ if(endMove ) return 0; // No Movement
+ if(endMoveRight) return 1; // Returns 1, assuming that only Left Motor is still running
+ if(endMoveLeft ) return 3; // Returns 2, Right Motor is running aloone
+ return 2; // Both Motors are still running!!!
+}
+
+void Creabot::setSpeed(float cm_per_second)
+{
+ setSpeedMot(motor_left,cm_per_second);
+ setSpeedMot(motor_right,cm_per_second);
+ last_speed = cm_per_second;
+}
+
+void Creabot::setSpeedMot(Motor *motor, float cm_per_second)
+{ if (cm_per_second <0.0001f)
+ motor->setStepTime_us( 1000000 );
+ else { uint32_t tick = motor->getStepsFullTurn();
+ motor->setStepTime_us( perimeter_wheel * 1000000 / cm_per_second / tick ) ;
+ }
+}
+
