Advertisement
Guest User

robotics proj5 follow-plan.cc

a guest
Nov 20th, 2017
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.91 KB | None | 0 0
  1. /**
  2. * follow-plan.cc
  3. *
  4. * Sample code for a robot that has two front bumpers and a laser, and
  5. * which is provided with localization data.
  6. *
  7. * The code also allows the controller to read and write a "plan", a sequence
  8. * of location that the robot should move to.
  9. *
  10. * Written by: Simon Parsons
  11. * Date: 10th November 2011
  12. *
  13. **/
  14.  
  15.  
  16. #include <iostream>
  17. #include <fstream>
  18. #include <libplayerc++/playerc++.h>
  19. using namespace PlayerCc;
  20.  
  21.  
  22. /**
  23. * Function headers
  24. *
  25. **/
  26.  
  27. player_pose2d_t readPosition(LocalizeProxy& lp);
  28. void printRobotData(BumperProxy& bp, player_pose2d_t pose);
  29. void printLaserData(LaserProxy& sp);
  30.  
  31. int readPlanLength(void);
  32. void readPlan(double *, int);
  33. void printPlan(double *,int);
  34. void writePlan(double *, int);
  35.  
  36. struct vector{
  37. double x;
  38. double y;
  39. };
  40.  
  41. /**
  42. * main()
  43. *
  44. **/
  45.  
  46. int main(int argc, char *argv[])
  47. {
  48.  
  49. // Variables
  50. int counter = 0;
  51. double speed; // How fast do we want the robot to go forwards?
  52. double turnrate; // How fast do we want the robot to turn?
  53. player_pose2d_t pose; // For handling localization data
  54.  
  55. // The set of coordinates that makes up the plan
  56.  
  57. int pLength;
  58. double *plan;
  59.  
  60. // Set up proxies. These are the names we will use to connect to
  61. // the interface to the robot.
  62. PlayerClient robot("localhost");
  63. BumperProxy bp(&robot,0);
  64. Position2dProxy pp(&robot,0);
  65. LocalizeProxy lp (&robot, 0);
  66. LaserProxy sp (&robot, 0);
  67.  
  68. // Allow the program to take charge of the motors (take care now)
  69. pp.SetMotorEnable(true);
  70.  
  71. // Plan handling
  72. //
  73. // A plan is an integer, n, followed by n doubles (n has to be
  74. // even). The first and second doubles are the initial x and y
  75. // (respectively) coordinates of the robot, the third and fourth
  76. // doubles give the first location that the robot should move to, and
  77. // so on. The last pair of doubles give the point at which the robot
  78. // should stop.
  79. pLength = readPlanLength(); // Find out how long the plan is from plan.txt
  80. plan = new double[pLength]; // Create enough space to store the plan
  81. readPlan(plan, pLength); // Read the plan from the file plan.txt.
  82. printPlan(plan,pLength); // Print the plan on the screen
  83. writePlan(plan, pLength); // Write the plan to the file plan-out.txt
  84.  
  85.  
  86. double targetx = 0;
  87. double targety = 0;
  88. double targeta = 0;
  89. bool targeta_reached = false;
  90. bool waypoint_reached = false;
  91. double initialy = 0;
  92. double initialx = 0;
  93. double distance = 0;
  94. bool finished = false;
  95. vector A;
  96. vector B;
  97. // Main control loop
  98. while(!finished)
  99. {
  100. // Update information from the robot.
  101. robot.Read();
  102. // Read new information about position
  103. pose = readPosition(lp);
  104. // Print data on the robot to the terminal
  105. printRobotData(bp, pose);
  106. // Print information about the laser. Check the counter first to stop
  107. // problems on startup
  108. if(counter > 2){
  109. printLaserData(sp);
  110. }
  111.  
  112. // Print data on the robot to the terminal --- turned off for now.
  113. // printRobotData(bp, pose);
  114.  
  115. // If either bumper is pressed, stop. Otherwise just go forwards
  116.  
  117. if(bp[0] || bp[1]){
  118. //speed= 0;
  119. //turnrate= 0;
  120. for(int i = 0; i < 10; i++){
  121. turnrate = 0;
  122. speed = -0.7;
  123. pp.SetSpeed(speed, turnrate);
  124. }
  125.  
  126.  
  127. }
  128. else {
  129. /*
  130. for i in waypoints
  131. go to waypoint
  132. */
  133. for(int i = 0; i < pLength; i = i + 2){
  134. waypoint_reached = false;
  135. targetx = plan[i];
  136. targety = plan[i+1];
  137. while(!waypoint_reached){
  138. // if it hit something
  139. if(bp[0] || bp[1]){
  140. int i_f = 20;
  141. // back up
  142. for(int i = 0; i < i_f/3; i++){
  143. robot.Read();
  144. turnrate = 0;
  145. speed = -0.5;
  146. pp.SetSpeed(speed, turnrate);
  147. std::cout << "i #1" << "\n";
  148. }
  149. // turn around
  150. for(int i = 0; i < i_f; i++){
  151. robot.Read();
  152. turnrate = 0.5;
  153. speed = 0;
  154. pp.SetSpeed(speed, turnrate);
  155. std::cout << "i #2" << "\n";
  156. }
  157. // do a semicircle
  158. for(int i = 0; i < i_f; i++){
  159. robot.Read();
  160. turnrate = -0.8;
  161. speed = 0.8;
  162. pp.SetSpeed(speed, turnrate);
  163. std::cout << "i #3" << "\n";
  164. }
  165.  
  166.  
  167.  
  168. }
  169. // Update information from the robot.
  170. robot.Read();
  171. // Read new information about position
  172. pose = readPosition(lp);
  173. // Print data on the robot to the terminal
  174. printRobotData(bp, pose);
  175. initialx = pose.px;
  176. initialy = pose.py;
  177.  
  178.  
  179. /*
  180. turn until we point in the right direction
  181. use proportional control to go straight until waypoint is reached
  182. */
  183.  
  184. //targeta = std::atan(std::abs(targety-initialy)/std::abs(targetx-initialx));
  185. targeta = std::acos((A.x*B.x+A.y*B.y)/(sqrt(A.x*A.x+A.y*A.y)*sqrt(B.x*B.x+B.y*B.y)));
  186. // targeta is the relative angular displacement
  187. distance = std::sqrt((initialx-targetx)*(initialx-targetx)+
  188. (initialy-targety)*(initialy-targety));
  189. //targeta_reached = !(pose.pa > targeta + 0.15 || pose.pa < targeta - 0.15);
  190. targeta_reached = targeta < 0.05 ;
  191. A.x = std::cos(pose.pa);
  192. A.y = std::sin(pose.pa);
  193. B.x = targetx - initialx;
  194. B.y = targety - initialy;
  195.  
  196. if(!targeta_reached){
  197. //turnrate = pose.pa-targeta < 0 ? 0.25 : -0.25;
  198. turnrate = A.x*B.y - B.x*A.y > 0 ? 0.25 : -0.25;
  199. speed = 0;
  200. } else {
  201. turnrate = 0;
  202. // PROPORTIONAL CONTROL
  203. speed = distance > 1 ? distance / 2 : 0.7;
  204. }
  205. waypoint_reached = std::abs(initialx-targetx)<0.3 && std::abs(initialy-targety)<0.3;
  206.  
  207. // What are we doing?
  208. std::cout << "Speed: " << speed << std::endl;
  209. std::cout << "Turn rate: " << turnrate << "\n";
  210. std::cout << "TargetX: " << targetx << "\n";
  211. std::cout << "TargetY: " << targety << "\n";
  212. std::cout << "TargetA: " << targeta*180/3.14 << "\n\n";
  213.  
  214.  
  215. counter++;
  216. pp.SetSpeed(speed, turnrate);
  217. } // end of while
  218. } // end of for
  219.  
  220. /*stop*/
  221.  
  222. //speed=0;
  223. //turnrate = 0;
  224.  
  225. }
  226.  
  227. // x y
  228. // -2.5 -6
  229. // -2.5 1.5
  230. // -1.5 2.5
  231. // 2.5 3.5
  232. // 6.5 6.5
  233.  
  234.  
  235.  
  236. // Send the commands to the robot
  237. pp.SetSpeed(speed, turnrate);
  238. // Count how many times we do this
  239. counter++;
  240.  
  241. finished = true;
  242. }
  243.  
  244. } // end of main()
  245.  
  246. /**
  247. * readPosition()
  248. *
  249. * Read the position of the robot from the localization proxy.
  250. *
  251. * The localization proxy gives us a hypothesis, and from that we extract
  252. * the mean, which is a pose.
  253. *
  254. **/
  255.  
  256. player_pose2d_t readPosition(LocalizeProxy& lp)
  257. {
  258.  
  259. player_localize_hypoth_t hypothesis;
  260. player_pose2d_t pose;
  261. uint32_t hCount;
  262.  
  263. // Need some messing around to avoid a crash when the proxy is
  264. // starting up.
  265.  
  266. hCount = lp.GetHypothCount();
  267.  
  268. if(hCount > 0){
  269. hypothesis = lp.GetHypoth(0);
  270. pose = hypothesis.mean;
  271. }
  272.  
  273. return pose;
  274. } // End of readPosition()
  275.  
  276.  
  277. void printLaserData(LaserProxy& sp)
  278. {
  279.  
  280. double maxRange, minLeft, minRight, range, bearing;
  281. int points;
  282.  
  283. maxRange = sp.GetMaxRange();
  284. minLeft = sp.MinLeft();
  285. minRight = sp.MinRight();
  286. range = sp.GetRange(5);
  287. bearing = sp.GetBearing(5);
  288. points = sp.GetCount();
  289.  
  290. //Uncomment this to print out useful laser data
  291. //std::cout << "Laser says..." << std::endl;
  292. //std::cout << "Maximum distance I can see: " << maxRange << std::endl;
  293. //std::cout << "Number of readings I return: " << points << std::endl;
  294. //std::cout << "Closest thing on left: " << minLeft << std::endl;
  295. //std::cout << "Closest thing on right: " << minRight << std::endl;
  296. //std::cout << "Range of a single point: " << range << std::endl;
  297. //std::cout << "Bearing of a single point: " << bearing << std::endl;
  298.  
  299. return;
  300. } // End of printLaserData()
  301.  
  302. /**
  303. * printRobotData
  304. *
  305. * Print out data on the state of the bumpers and the current location
  306. * of the robot.
  307. *
  308. **/
  309.  
  310. void printRobotData(BumperProxy& bp, player_pose2d_t pose)
  311. {
  312.  
  313. // Print out what the bumpers tell us:
  314. std::cout << "Left bumper: " << bp[0] << std::endl;
  315. std::cout << "Right bumper: " << bp[1] << std::endl;
  316. // Can also print the bumpers with:
  317. //std::cout << bp << std::endl;
  318.  
  319. // Print out where we are
  320. std::cout << "We are at" << std::endl;
  321. std::cout << "X: " << pose.px << std::endl;
  322. std::cout << "Y: " << pose.py << std::endl;
  323. std::cout << "A: " << pose.pa*180/3.14 << std::endl;
  324.  
  325.  
  326. } // End of printRobotData()
  327.  
  328. /**
  329. * readPlanLength
  330. *
  331. * Open the file plan.txt and read the first element, which should be
  332. * an even integer, and return it.
  333. *
  334. **/
  335.  
  336. int readPlanLength(void)
  337. {
  338. int length;
  339.  
  340. std::ifstream planFile;
  341. planFile.open("plan.txt");
  342.  
  343. planFile >> length;
  344. planFile.close();
  345.  
  346. // Some minimal error checking
  347. if((length % 2) != 0){
  348. std::cout << "The plan has mismatched x and y coordinates" << std::endl;
  349. exit(1);
  350. }
  351.  
  352. return length;
  353.  
  354. } // End of readPlanLength
  355.  
  356. /**
  357. * readPlan
  358. *
  359. * Given the number of coordinates, read them in from plan.txt and put
  360. * them in the array plan.
  361. *
  362. **/
  363.  
  364. void readPlan(double *plan, int length)
  365. {
  366. int skip;
  367.  
  368. std::ifstream planFile;
  369. planFile.open("plan.txt");
  370.  
  371. planFile >> skip;
  372. for(int i = 0; i < length; i++){
  373. planFile >> plan[i];
  374. }
  375.  
  376. planFile.close();
  377.  
  378. } // End of readPlan
  379.  
  380. /**
  381. * printPlan
  382. *
  383. * Print the plan on the screen, two coordinates to a line, x then y
  384. * with a header to remind us which is which.
  385. *
  386. **/
  387.  
  388. void printPlan(double *plan , int length)
  389. {
  390. std::cout << std::endl;
  391. std::cout << " x y" << std::endl;
  392. for(int i = 0; i < length; i++){
  393. std::cout.width(5);
  394. std::cout << plan[i] << " ";
  395. if((i > 0) && ((i % 2) != 0)){
  396. std::cout << std::endl;
  397. }
  398. }
  399. std::cout << std::endl;
  400.  
  401. } // End of printPlan
  402.  
  403.  
  404. /**
  405. * writePlan
  406. *
  407. * Send the plan to the file plan-out.txt, preceeded by the information
  408. * about how long it is.
  409. *
  410. **/
  411.  
  412. void writePlan(double *plan , int length)
  413. {
  414. std::ofstream planFile;
  415. planFile.open("plan-out.txt");
  416.  
  417. planFile << length << " ";
  418. for(int i = 0; i < length; i++){
  419. planFile << plan[i] << " ";
  420. }
  421.  
  422. planFile.close();
  423.  
  424. } // End of writePlan
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement