Dependencies: ISR_Mini-explorer mbed
Fork of roboticLab_withclass by
Revision 1:20f48907c726, committed 2017-07-03
- Comitter:
- geotsam
- Date:
- Mon Jul 03 17:06:16 2017 +0000
- Parent:
- 0:9f7ee7ed13e4
- Commit message:
- added first lab stuff
Changed in this revision
diff -r 9f7ee7ed13e4 -r 20f48907c726 MiniExplorerCoimbra.cpp --- a/MiniExplorerCoimbra.cpp Mon Jun 26 12:05:20 2017 +0000 +++ b/MiniExplorerCoimbra.cpp Mon Jul 03 17:06:16 2017 +0000 @@ -14,11 +14,15 @@ this->radiusWheels=3.25; this->distanceWheels=7.2; + this->k_linear=10; + this->k_angular=200; this->khro=12; this->ka=30; this->kb=-13; this->kv=200; this->kh=200; + this->kd=5; + this->speed=300; this->rangeForce=30; this->attractionConstantForce=10000; @@ -47,6 +51,70 @@ this->thetaWorld=theta+PI/2; } +void MiniExplorerCoimbra::go_to_point(float targetXWorld, float targetYWorld) { + + float angleError; //angle error + float d; //distance from target + float k_linear=10, k_angular=200; + float angularLeft, angularRight, linear, angular; + int speed=300; + + do { + //Updating X,Y and theta with the odometry values + this->myOdometria(); + + //Computing angle error and distance towards the target value + angleError = atan2((targetYWorld-this->yWorld),(targetXWorld-this->xWorld))-this->thetaWorld; + if(angleError>PI) angleError=-(angleError-PI); + else if(angleError<-PI) angleError=-(angleError+PI); + pc.printf("\n\r error=%f",angleError); + + d=this->dist(this->xWorld, this->yWorld, targetXWorld, targetYWorld); + pc.printf("\n\r dist=%f/n", d); + + //Computing linear and angular velocities + linear=k_linear*d; + angular=k_angular*angleError; + angularLeft=(linear-0.5*this->distanceWheels*angular)/this->radiusWheels; + angularRight=(linear+0.5*this->distanceWheels*angular)/this->radiusWheels; + + + //Normalize speed for motors + if(angularLeft>angularRight) { + angularRight=speed*angularRight/angularLeft; + angularLeft=speed; + } else { + angularLeft=speed*angularLeft/angularRight; + angularRight=speed; + } + + pc.printf("\n\r X=%f", this->xWorld); + pc.printf("\n\r Y=%f", this->yWorld); + pc.printf("\n\r theta=%f", this->thetaWorld); + + //Updating motor velocities + if(angularLeft>0){ + leftMotor(1,angularLeft); + } + else{ + leftMotor(0,-angularLeft); + } + + if(angularRight>0){ + rightMotor(1,angularRight); + } + else{ + rightMotor(0,-angularRight); + } + + wait(0.5); + } while(d>1); + + //Stop at the end + leftMotor(1,0); + rightMotor(1,0); +} + //generate a position randomly and makes the robot go there while updating the map void MiniExplorerCoimbra::randomize_and_map() { //TODO check that it's aurelien's work @@ -116,12 +184,46 @@ rightMotor(1,0); } + +//move of targetXWorld and targetYWorld ending in a targetAngleWorld +void MiniExplorerCoimbra::go_to_point_with_angle_first_lab(float targetXWorld, float targetYWorld, float targetAngleWorld) { + float dt; + Timer t; + float distanceToTarget; + do { + //Timer stuff + dt = t.read(); + t.reset(); + t.start(); + + //Updating X,Y and theta with the odometry values + this->myOdometria(); + + + //Updating motor velocities + distanceToTarget=this->update_angular_speed_wheels_go_to_point_with_angle(targetXWorld,targetYWorld,targetAngleWorld,dt); + + wait(0.2); + //Timer stuff + t.stop(); + pc.printf("\n\rdist to target= %f",distanceToTarget); + + } while(distanceToTarget>1 || (abs(targetAngleWorld-this->thetaWorld)>0.1)); + + //Stop at the end + leftMotor(1,0); + rightMotor(1,0); + pc.printf("\r\nReached Target!"); +} + float MiniExplorerCoimbra::update_angular_speed_wheels_go_to_point_with_angle(float targetXWorld, float targetYWorld, float targetAngleWorld, float dt){ //compute_angles_and_distance //atan2 take the deplacement on x and the deplacement on y as parameters float angleToPoint = atan2((targetYWorld-this->yWorld),(targetXWorld-this->xWorld))-this->thetaWorld; - angleToPoint = atan(sin(angleToPoint)/cos(angleToPoint)); - //rho is the distance to the point of arrival + + if(angleToPoint>PI) angleToPoint=-(angleToPoint-PI); + else if(angleToPoint<-PI) angleToPoint=-(angleToPoint+PI); //rho is the distance to the point of arrival + float rho = dist(targetXWorld,targetYWorld,this->xWorld,this->yWorld); float distanceToTarget = rho; //TODO check that @@ -144,21 +246,27 @@ linear=-this->khro*rho; angular=-this->ka*angleToPoint-this->kb*beta; } - float angular_left=(linear-0.5*this->distanceWheels*angular)/this->radiusWheels; - float angular_right=(linear+0.5*this->distanceWheels*angular)/this->radiusWheels; + + float angularLeft=(linear-0.5*this->distanceWheels*angular)/this->radiusWheels; + float angularRight=(linear+0.5*this->distanceWheels*angular)/this->radiusWheels; + + //Slowing down at the end for more precision + if (distanceToTarget<30) { + this->speed = distanceToTarget*10; + } //Normalize speed for motors - if(angular_left>angular_right) { - angular_right=this->speed*angular_right/angular_left; - angular_left=this->speed; + if(angularLeft>angularRight) { + angularRight=this->speed*angularRight/angularLeft; + angularLeft=this->speed; } else { - angular_left=this->speed*angular_left/angular_right; - angular_right=this->speed; + angularLeft=this->speed*angularLeft/angularRight; + angularRight=this->speed; } //compute_linear_angular_velocities - leftMotor(1,angular_left); - rightMotor(1,angular_right); + leftMotor(1,angularLeft); + rightMotor(1,angularRight); return distanceToTarget; } @@ -428,6 +536,57 @@ rightMotor(this->sign2(angularRight),abs(angularRight)); } +void MiniExplorerCoimbra::go_to_line_first_lab(float line_a, float line_b, float line_c){ + float lineAngle; + float angleError; + float linear; + float angular; + float d; + + //line angle is beetween pi/2 and -pi/2 + + if(line_b!=0){ + lineAngle=atan(line_a/-line_b); + } + else{ + lineAngle=1.5708; + } + + do{ + this->myOdometria(); + //Computing angle error + angleError = lineAngle-this->thetaWorld;//TODO that I m not sure + + if(angleError>PI) angleError=-(angleError-PI); + else if(angleError<-PI) angleError=-(angleError+PI); + + d=this->distFromLine(xWorld, yWorld, line_a, line_b, line_c); + + //Calculating velocities + linear= this->kv*(3.14); + angular=-this->kd*d + this->kh*angleError; + + float angularLeft=(linear-0.5*this->distanceWheels*angular)/this->radiusWheels; + float angularRight=(linear+0.5*this->distanceWheels*angular)/this->radiusWheels; + + //Normalize speed for motors + if(abs(angularLeft)>abs(angularRight)) { + angularRight=this->speed*abs(angularRight/angularLeft)*this->sign1(angularRight); + angularLeft=this->speed*this->sign1(angularLeft); + } + else { + angularLeft=this->speed*abs(angularLeft/angularRight)*this->sign1(angularLeft); + angularRight=this->speed*this->sign1(angularRight); + } + + pc.printf("\r\nd = %f", d); + pc.printf("\r\nerror = %f\n", angleError); + + leftMotor(this->sign2(angularLeft),abs(angularLeft)); + rightMotor(this->sign2(angularRight),abs(angularRight)); + }while(1); +} + void MiniExplorerCoimbra::update_force(int widthIndice, int heightIndice, float* forceRepulsionComputedX, float* forceRepulsionComputedY ){ //get the coordonate of the map and the robot in the ortonormal space float xWorldCell=this->map.cell_width_coordinate_to_world(widthIndice); @@ -458,6 +617,10 @@ return 0; } +float MiniExplorerCoimbra::distFromLine(float robot_x, float robot_y, float line_a, float line_b, float line_c){ + return abs((line_a*robot_x+line_b*robot_y+line_c)/sqrt(line_a*line_a+line_b*line_b)); +} + /* void MiniExplorerCoimbra::test_procedure_lab_4(){ this->map.fill_map_with_initial();
diff -r 9f7ee7ed13e4 -r 20f48907c726 MiniExplorerCoimbra.hpp --- a/MiniExplorerCoimbra.hpp Mon Jun 26 12:05:20 2017 +0000 +++ b/MiniExplorerCoimbra.hpp Mon Jul 03 17:06:16 2017 +0000 @@ -36,6 +36,9 @@ float kb; float kv; float kh; + float kd; + float k_linear; + float k_angular; float rangeForce; float attractionConstantForce; @@ -49,12 +52,19 @@ //move of targetXWorld and targetYWorld ending in a targetAngleWorld void go_to_point_with_angle(float targetXWorld, float targetYWorld, float targetAngleWorld); + //move of targetXWorld and targetYWorld ending in a targetAngleWorld without checking the sonars + void go_to_point_with_angle_first_lab(float targetXWorld, float targetYWorld, float targetAngleWorld); + //use virtual force field void try_to_reach_target(float targetXWorld,float targetYWorld); void test_procedure_lab_4(); + void go_to_point(float targetXWorld, float targetYWorld); + + void go_to_line_first_lab(float line_a, float line_b, float line_c); + private: void myOdometria(); @@ -70,6 +80,8 @@ //Distance computation function float dist(float x1, float y1, float x2, float y2); + float distFromLine(float robot_x, float robot_y, float line_a, float line_b, float line_c); + /*angleToTarget is obtained through atan2 so it s: < 0 if the angle is bettween PI and 2pi on a trigo circle > 0 if it is between 0 and PI
diff -r 9f7ee7ed13e4 -r 20f48907c726 main.cpp --- a/main.cpp Mon Jun 26 12:05:20 2017 +0000 +++ b/main.cpp Mon Jul 03 17:06:16 2017 +0000 @@ -2,8 +2,14 @@ int main(){ MiniExplorerCoimbra myRobot(0,0,0); + //test lab1 + //myRobot.go_to_point(-45,-80); + myRobot.go_to_line_first_lab(-1,1,0); + //myRobot.go_to_point_with_angle_first_lab(45,80,3.14); + //test lab2 //myRobot.randomize_and_map(); + //test lab3 //myRobot.try_to_reach_target(50,30); return 0;