This program is for an autonomous robot for the competition at the Hochschule Luzern. http://cruisingcrepe.wordpress.com/ We are one of the 32 teams. http://cruisingcrepe.wordpress.com/ The postition control is based on this Documentation: Control of Wheeled Mobile Robots: An Experimental Overview from Alessandro De Luca, Giuseppe Oriolo, Marilena Vendittelli. For more information see here: http://www.dis.uniroma1.it/~labrob/pub/papers/Ramsete01.pdf

Dependencies:   mbed

Fork of autonomous Robot Android by Christian Burri

Committer:
chrigelburri
Date:
Thu Mar 07 09:47:07 2013 +0000
Revision:
3:92ba0254af87
Parent:
2:d8e1613dc38b
Child:
5:48a258f6335e
bitte kommentare korriegieren;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
chrigelburri 0:31f7be68e52d 1 #include "RobotControl.h"
chrigelburri 0:31f7be68e52d 2
chrigelburri 0:31f7be68e52d 3 using namespace std;
chrigelburri 0:31f7be68e52d 4
chrigelburri 1:6cd533a712c6 5 RobotControl::RobotControl(MaxonESCON* motorControllerLeft, MaxonESCON* motorControllerRight, /*HMC6352* compass,*/ float period) : Task(period)
chrigelburri 0:31f7be68e52d 6 {
chrigelburri 0:31f7be68e52d 7 /* get peripherals */
chrigelburri 0:31f7be68e52d 8 this->motorControllerLeft = motorControllerLeft;
chrigelburri 0:31f7be68e52d 9 this->motorControllerRight = motorControllerRight;
chrigelburri 1:6cd533a712c6 10 // this->compass = compass;
chrigelburri 0:31f7be68e52d 11 this->period = period;
chrigelburri 0:31f7be68e52d 12
chrigelburri 0:31f7be68e52d 13 /* initialize peripherals */
chrigelburri 0:31f7be68e52d 14 motorControllerLeft->enable(false);
chrigelburri 0:31f7be68e52d 15 motorControllerRight->enable(false);
chrigelburri 0:31f7be68e52d 16
chrigelburri 0:31f7be68e52d 17 /* initialize remaining state values */
chrigelburri 0:31f7be68e52d 18 speed = 0.0f;
chrigelburri 0:31f7be68e52d 19 omega = 0.0f;
chrigelburri 0:31f7be68e52d 20
chrigelburri 0:31f7be68e52d 21 motorControllerLeft->setPulses(0);
chrigelburri 0:31f7be68e52d 22 motorControllerRight->setPulses(0);
chrigelburri 0:31f7be68e52d 23
chrigelburri 0:31f7be68e52d 24 Desired.setAcceleration(ACCELERATION);
chrigelburri 0:31f7be68e52d 25 Desired.setThetaAcceleration(THETA_ACCELERATION);
chrigelburri 0:31f7be68e52d 26 }
chrigelburri 0:31f7be68e52d 27
chrigelburri 1:6cd533a712c6 28 RobotControl::~RobotControl()
chrigelburri 0:31f7be68e52d 29 {
chrigelburri 0:31f7be68e52d 30
chrigelburri 0:31f7be68e52d 31 }
chrigelburri 0:31f7be68e52d 32
chrigelburri 0:31f7be68e52d 33 void RobotControl::setEnable(bool enable)
chrigelburri 0:31f7be68e52d 34 {
chrigelburri 0:31f7be68e52d 35 motorControllerLeft->enable(enable);
chrigelburri 0:31f7be68e52d 36 motorControllerRight->enable(enable);
chrigelburri 0:31f7be68e52d 37 }
chrigelburri 0:31f7be68e52d 38
chrigelburri 0:31f7be68e52d 39 bool RobotControl::isEnabled()
chrigelburri 0:31f7be68e52d 40 {
chrigelburri 0:31f7be68e52d 41 return (motorControllerLeft->isEnabled() && motorControllerRight->isEnabled());
chrigelburri 0:31f7be68e52d 42 }
chrigelburri 0:31f7be68e52d 43
chrigelburri 1:6cd533a712c6 44 void RobotControl::setAcceleration(float acceleration)
chrigelburri 0:31f7be68e52d 45 {
chrigelburri 1:6cd533a712c6 46 Desired.setAcceleration(acceleration);
chrigelburri 0:31f7be68e52d 47 }
chrigelburri 0:31f7be68e52d 48
chrigelburri 1:6cd533a712c6 49 void RobotControl::setThetaAcceleration(float acceleration)
chrigelburri 0:31f7be68e52d 50 {
chrigelburri 1:6cd533a712c6 51 Desired.setThetaAcceleration(acceleration);
chrigelburri 0:31f7be68e52d 52 }
chrigelburri 0:31f7be68e52d 53
chrigelburri 0:31f7be68e52d 54 void RobotControl::setDesiredSpeed(float speed)
chrigelburri 0:31f7be68e52d 55 {
chrigelburri 0:31f7be68e52d 56 this->speed = speed;
chrigelburri 0:31f7be68e52d 57 }
chrigelburri 0:31f7be68e52d 58
chrigelburri 0:31f7be68e52d 59 void RobotControl::setDesiredOmega(float omega)
chrigelburri 0:31f7be68e52d 60 {
chrigelburri 0:31f7be68e52d 61 this->omega = omega;
chrigelburri 0:31f7be68e52d 62 }
chrigelburri 0:31f7be68e52d 63
chrigelburri 1:6cd533a712c6 64 void RobotControl::setxPosition(float xposition)
chrigelburri 0:31f7be68e52d 65 {
chrigelburri 1:6cd533a712c6 66 Desired.xposition = xposition;
chrigelburri 0:31f7be68e52d 67 }
chrigelburri 0:31f7be68e52d 68
chrigelburri 1:6cd533a712c6 69 void RobotControl::setyPosition(float yposition)
chrigelburri 0:31f7be68e52d 70 {
chrigelburri 1:6cd533a712c6 71 Desired.yposition = yposition;
chrigelburri 0:31f7be68e52d 72 }
chrigelburri 0:31f7be68e52d 73
chrigelburri 0:31f7be68e52d 74 void RobotControl::setTheta(float theta)
chrigelburri 0:31f7be68e52d 75 {
chrigelburri 0:31f7be68e52d 76 Desired.theta = theta;
chrigelburri 0:31f7be68e52d 77 }
chrigelburri 0:31f7be68e52d 78
chrigelburri 2:d8e1613dc38b 79 void RobotControl::setPositionAngle(float xposition, float yposition, float theta)
chrigelburri 2:d8e1613dc38b 80 {
chrigelburri 2:d8e1613dc38b 81 setxPosition(xposition);
chrigelburri 2:d8e1613dc38b 82 setyPosition(yposition);
chrigelburri 2:d8e1613dc38b 83 setTheta(theta);
chrigelburri 2:d8e1613dc38b 84 }
chrigelburri 2:d8e1613dc38b 85
chrigelburri 1:6cd533a712c6 86 float RobotControl::getTheta()
chrigelburri 1:6cd533a712c6 87 {
chrigelburri 1:6cd533a712c6 88 return Desired.theta;
chrigelburri 1:6cd533a712c6 89 }
chrigelburri 1:6cd533a712c6 90
chrigelburri 0:31f7be68e52d 91 float RobotControl::getDesiredSpeed()
chrigelburri 0:31f7be68e52d 92 {
chrigelburri 0:31f7be68e52d 93 return speed;
chrigelburri 0:31f7be68e52d 94 }
chrigelburri 0:31f7be68e52d 95
chrigelburri 0:31f7be68e52d 96 float RobotControl::getActualSpeed()
chrigelburri 0:31f7be68e52d 97 {
chrigelburri 0:31f7be68e52d 98 return Actual.speed;
chrigelburri 0:31f7be68e52d 99 }
chrigelburri 0:31f7be68e52d 100
chrigelburri 0:31f7be68e52d 101 float RobotControl::getDesiredOmega()
chrigelburri 0:31f7be68e52d 102 {
chrigelburri 0:31f7be68e52d 103 return omega;
chrigelburri 0:31f7be68e52d 104 }
chrigelburri 0:31f7be68e52d 105
chrigelburri 0:31f7be68e52d 106 float RobotControl::getActualOmega()
chrigelburri 0:31f7be68e52d 107 {
chrigelburri 0:31f7be68e52d 108 return Actual.omega;
chrigelburri 0:31f7be68e52d 109 }
chrigelburri 0:31f7be68e52d 110
chrigelburri 0:31f7be68e52d 111 float RobotControl::getxActualPosition()
chrigelburri 0:31f7be68e52d 112 {
chrigelburri 0:31f7be68e52d 113 return Actual.getxPosition();
chrigelburri 0:31f7be68e52d 114 }
chrigelburri 0:31f7be68e52d 115
chrigelburri 0:31f7be68e52d 116 float RobotControl::getxPositionError()
chrigelburri 0:31f7be68e52d 117 {
chrigelburri 0:31f7be68e52d 118 return Desired.getxPosition()-Actual.getxPosition();
chrigelburri 0:31f7be68e52d 119 }
chrigelburri 0:31f7be68e52d 120
chrigelburri 0:31f7be68e52d 121 float RobotControl::getyActualPosition()
chrigelburri 0:31f7be68e52d 122 {
chrigelburri 0:31f7be68e52d 123 return Actual.getyPosition();
chrigelburri 0:31f7be68e52d 124 }
chrigelburri 0:31f7be68e52d 125
chrigelburri 0:31f7be68e52d 126 float RobotControl::getyPositionError()
chrigelburri 0:31f7be68e52d 127 {
chrigelburri 0:31f7be68e52d 128 return Desired.getyPosition()-Actual.getyPosition();
chrigelburri 0:31f7be68e52d 129 }
chrigelburri 0:31f7be68e52d 130
chrigelburri 0:31f7be68e52d 131 float RobotControl::getActualTheta()
chrigelburri 0:31f7be68e52d 132 {
chrigelburri 0:31f7be68e52d 133 return Actual.getTheta();
chrigelburri 0:31f7be68e52d 134 }
chrigelburri 0:31f7be68e52d 135
chrigelburri 0:31f7be68e52d 136 float RobotControl::getThetaError()
chrigelburri 0:31f7be68e52d 137 {
chrigelburri 0:31f7be68e52d 138 return Desired.getTheta()-Actual.getTheta();
chrigelburri 0:31f7be68e52d 139 }
chrigelburri 0:31f7be68e52d 140
chrigelburri 1:6cd533a712c6 141 float RobotControl::getDistanceError()
chrigelburri 1:6cd533a712c6 142 {
chrigelburri 1:6cd533a712c6 143 return sqrt( ( getxPositionError() * getxPositionError() ) + (getyPositionError() * getyPositionError() ) );
chrigelburri 1:6cd533a712c6 144 }
chrigelburri 1:6cd533a712c6 145
chrigelburri 1:6cd533a712c6 146 float RobotControl::getThetaErrorToGoal()
chrigelburri 0:31f7be68e52d 147 {
chrigelburri 3:92ba0254af87 148 return PiRange(atan2(getyPositionError(),getxPositionError()) - getActualTheta());
chrigelburri 3:92ba0254af87 149 /*float temp;
chrigelburri 2:d8e1613dc38b 150 temp = atan2(getyPositionError(),getxPositionError()) - getActualTheta();
chrigelburri 2:d8e1613dc38b 151
chrigelburri 2:d8e1613dc38b 152 if(temp <= -PI) {
chrigelburri 2:d8e1613dc38b 153 temp += 2* PI;
chrigelburri 2:d8e1613dc38b 154 } else if (temp > PI) {
chrigelburri 2:d8e1613dc38b 155 temp -= 2* PI;
chrigelburri 2:d8e1613dc38b 156 } else {
chrigelburri 2:d8e1613dc38b 157 //nothing
chrigelburri 2:d8e1613dc38b 158 }
chrigelburri 3:92ba0254af87 159 return temp;*/
chrigelburri 1:6cd533a712c6 160 }
chrigelburri 1:6cd533a712c6 161
chrigelburri 1:6cd533a712c6 162 float RobotControl::getThetaGoal()
chrigelburri 1:6cd533a712c6 163 {
chrigelburri 3:92ba0254af87 164 return PiRange(atan2(getyPositionError(),getxPositionError()) - getTheta());
chrigelburri 2:d8e1613dc38b 165
chrigelburri 3:92ba0254af87 166 /*
chrigelburri 2:d8e1613dc38b 167 if(temp <= -PI) {
chrigelburri 2:d8e1613dc38b 168 temp += 2* PI;
chrigelburri 2:d8e1613dc38b 169 } else if (temp > PI) {
chrigelburri 2:d8e1613dc38b 170 temp -= 2* PI;
chrigelburri 2:d8e1613dc38b 171 } else {
chrigelburri 2:d8e1613dc38b 172 //nothing
chrigelburri 2:d8e1613dc38b 173 }
chrigelburri 3:92ba0254af87 174 return temp;*/
chrigelburri 1:6cd533a712c6 175 }
chrigelburri 1:6cd533a712c6 176
chrigelburri 1:6cd533a712c6 177 void RobotControl::setAllToZero(float xZeroPos, float yZeroPos, float theta)
chrigelburri 1:6cd533a712c6 178 {
chrigelburri 1:6cd533a712c6 179 Actual.setState(xZeroPos, yZeroPos, theta, 0.0f, 0.0f);
chrigelburri 0:31f7be68e52d 180 Desired.setState(0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
chrigelburri 0:31f7be68e52d 181 stateLeft.setState(0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
chrigelburri 0:31f7be68e52d 182 stateRight.setState(0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
chrigelburri 0:31f7be68e52d 183 speed = 0.0f;
chrigelburri 0:31f7be68e52d 184 omega = 0.0f;
chrigelburri 0:31f7be68e52d 185 }
chrigelburri 0:31f7be68e52d 186
chrigelburri 0:31f7be68e52d 187 void RobotControl::run()
chrigelburri 0:31f7be68e52d 188 {
chrigelburri 1:6cd533a712c6 189 ///// DAs kan glaub raus ab hier
chrigelburri 2:d8e1613dc38b 190 /////////////////////////////////////////////////////////7
chrigelburri 0:31f7be68e52d 191 /* motion planning */
chrigelburri 0:31f7be68e52d 192 if (isEnabled()) {
chrigelburri 1:6cd533a712c6 193 ///// DAs kan glaub raus bis hier
chrigelburri 0:31f7be68e52d 194 Desired.increment(speed, omega, period);
chrigelburri 1:6cd533a712c6 195
chrigelburri 2:d8e1613dc38b 196 ///// DAs kan glaub raus bis hier
chrigelburri 1:6cd533a712c6 197
chrigelburri 0:31f7be68e52d 198 } else {
chrigelburri 0:31f7be68e52d 199 speed = 0.0f;
chrigelburri 0:31f7be68e52d 200 omega = 0.0f;
chrigelburri 0:31f7be68e52d 201 Desired.setState(&Actual);
chrigelburri 0:31f7be68e52d 202 }
chrigelburri 0:31f7be68e52d 203
chrigelburri 0:31f7be68e52d 204 /* position calculation */
chrigelburri 0:31f7be68e52d 205
chrigelburri 0:31f7be68e52d 206 /* Set the state of speed from Left und Right Wheel*/
chrigelburri 1:6cd533a712c6 207 stateLeft.speed = motorControllerLeft->getActualSpeed() * 2.0f * WHEEL_RADIUS * PI * GEAR;
chrigelburri 1:6cd533a712c6 208 stateRight.speed = - motorControllerRight->getActualSpeed() * 2.0f * WHEEL_RADIUS * PI * GEAR;
chrigelburri 0:31f7be68e52d 209
chrigelburri 0:31f7be68e52d 210 /* translational speed of the Robot (average) */
chrigelburri 0:31f7be68e52d 211 Actual.speed = ( stateRight.speed + stateLeft.speed ) / 2.0f;
chrigelburri 0:31f7be68e52d 212
chrigelburri 0:31f7be68e52d 213 /* rotational speed of the Robot */
chrigelburri 0:31f7be68e52d 214 Actual.omega = ( stateRight.speed - stateLeft.speed ) / WHEEL_DISTANCE;
chrigelburri 0:31f7be68e52d 215
chrigelburri 1:6cd533a712c6 216 /* rotational theta of the Robot integrate the omega with the time*/
chrigelburri 0:31f7be68e52d 217 Actual.theta += Actual.omega * period;
chrigelburri 3:92ba0254af87 218 Actual.theta = PiRange(Actual.theta);
chrigelburri 3:92ba0254af87 219 /*
chrigelburri 3:92ba0254af87 220 if(Actual.theta <= -PI) {
chrigelburri 3:92ba0254af87 221 Actual.theta += 2* PI;
chrigelburri 3:92ba0254af87 222 } else if (Actual.theta > PI) {
chrigelburri 3:92ba0254af87 223 Actual.theta -= 2* PI;
chrigelburri 3:92ba0254af87 224 } else {
chrigelburri 3:92ba0254af87 225 //nothing
chrigelburri 3:92ba0254af87 226 }
chrigelburri 3:92ba0254af87 227 */
chrigelburri 1:6cd533a712c6 228 /* translational X and Y Position. integrate the speed with the time */
chrigelburri 1:6cd533a712c6 229 Actual.xposition += (Actual.speed * period * cos(Actual.theta));
chrigelburri 1:6cd533a712c6 230 Actual.yposition += (Actual.speed * period * sin(Actual.theta));
chrigelburri 0:31f7be68e52d 231
chrigelburri 1:6cd533a712c6 232 // Actual.thetaCompass = compass->getFilteredAngle();
chrigelburri 1:6cd533a712c6 233 /* translational X and Y Position. integrate the speed with the time theta from compass */
chrigelburri 1:6cd533a712c6 234 // Actual.xposition += - (Actual.speed * period * cos(Actual.thetaCompass));
chrigelburri 1:6cd533a712c6 235 // Actual.yposition += (Actual.speed * period * sin(Actual.thetaCompass));
chrigelburri 2:d8e1613dc38b 236
chrigelburri 1:6cd533a712c6 237 /* motor control */
chrigelburri 1:6cd533a712c6 238 if ( isEnabled() && ( getDistanceError() >= MIN_DISTANCE_ERROR ) ) {
chrigelburri 0:31f7be68e52d 239
chrigelburri 1:6cd533a712c6 240 /* postition control */
chrigelburri 2:d8e1613dc38b 241
chrigelburri 1:6cd533a712c6 242 speed = K1 * getDistanceError() * cos( getThetaErrorToGoal() );
chrigelburri 2:d8e1613dc38b 243 omega = K2 * getThetaErrorToGoal() +
chrigelburri 2:d8e1613dc38b 244 K1 * ( ( sin(getThetaErrorToGoal()) * cos(getThetaErrorToGoal()) ) / (getThetaErrorToGoal()) ) * ( getThetaErrorToGoal() + K3 * getThetaGoal() );
chrigelburri 0:31f7be68e52d 245
chrigelburri 1:6cd533a712c6 246 motorControllerLeft->setVelocity( ( ( (2 * speed) - (WHEEL_DISTANCE * omega) ) / 2 ) / (2 * WHEEL_RADIUS * PI) * GEAR );
chrigelburri 1:6cd533a712c6 247 motorControllerRight->setVelocity(-( ( (2 * speed) + (WHEEL_DISTANCE * omega) ) / 2) / (2 * WHEEL_RADIUS * PI) * GEAR );
chrigelburri 0:31f7be68e52d 248
chrigelburri 0:31f7be68e52d 249 } else {
chrigelburri 0:31f7be68e52d 250
chrigelburri 0:31f7be68e52d 251 motorControllerLeft->setVelocity(0.0f);
chrigelburri 0:31f7be68e52d 252 motorControllerRight->setVelocity(0.0f);
chrigelburri 0:31f7be68e52d 253
chrigelburri 1:6cd533a712c6 254 }
chrigelburri 0:31f7be68e52d 255 }
chrigelburri 3:92ba0254af87 256
chrigelburri 3:92ba0254af87 257 float RobotControl::PiRange(float theta)
chrigelburri 3:92ba0254af87 258 {
chrigelburri 3:92ba0254af87 259 if(theta <= -PI) {
chrigelburri 3:92ba0254af87 260 return theta += 2*PI;
chrigelburri 3:92ba0254af87 261 } else if (theta > PI) {
chrigelburri 3:92ba0254af87 262 return theta -= 2*PI;
chrigelburri 3:92ba0254af87 263 } else {
chrigelburri 3:92ba0254af87 264 return theta;
chrigelburri 3:92ba0254af87 265 }
chrigelburri 3:92ba0254af87 266 }
chrigelburri 3:92ba0254af87 267