Advertisement
Guest User

Untitled

a guest
Nov 18th, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.48 KB | None | 0 0
  1. #include <Arduino_FreeRTOS.h>
  2. #include <math.h>
  3. #include <Wire.h>
  4.  
  5. #include "SparkFun_BNO080_Arduino_Library.h"
  6.  
  7.  
  8. //----------------------------------------------------- IMU -----------------------------------------------------
  9. BNO080 myIMU;
  10.  
  11. // Get the euler angles
  12. struct Euler {
  13. float yaw;
  14. float pitch;
  15. float roll;
  16. };
  17. struct Quat {
  18. float i;
  19. float j;
  20. float k;
  21. float real;
  22. };
  23.  
  24.  
  25. Euler getAngles(Quat q, bool degrees);
  26.  
  27. Quat myQuat;
  28. Euler eul;
  29.  
  30. bool gotOffset = false;
  31.  
  32. float headingOffset = 0;
  33. float angle = 0;
  34. float robotHeading = 0;
  35. float softwareHeading = 90;
  36. //----------------------------------------------------------------------------------------------------------
  37.  
  38.  
  39. // ----------------------------------------------------- MOTORS -----------------------------------------------------
  40. #define DISTANCEPERTICK (diameterOfWheel * PI) / numberOfEncoders
  41. #define ANGLEPERTICK (DISTANCEPERTICK * 360)/ ( distanceBetweenWheel * PI)
  42. const int diameterOfWheel = 65;
  43. const int numberOfEncoders = 375;
  44. const int distanceBetweenWheel = 206;
  45. int speedOfMotors = 60;
  46.  
  47. const int IN1 = 13;
  48. const int IN2 = 12;
  49. const int IN3 = 11;
  50. const int IN4 = 10;
  51.  
  52. const int M2PWM = 5;
  53.  
  54. //m1 left
  55. //m2 right
  56.  
  57. const int m1enc1 = 2;
  58. //const int m1enc2 = 14; // NOT USED
  59. const int m2enc1 = 3;
  60. //const int m2enc2 = 4; // NOT USED
  61.  
  62. volatile long leftEnc = 0, rightEnc = 0;
  63.  
  64. int turnSpeed = 120;// ----------------------------------------------------------------------------------------------------------
  65.  
  66.  
  67. // define two tasks for Blink & AnalogRead
  68. void TaskReadIMU( void *pvParameters );
  69. void TaskMoveRobot( void *pvParameters );
  70.  
  71. long counter;
  72.  
  73. // the setup function runs once when you press reset or power the board
  74. void setup() {
  75.  
  76. // initialize serial communication at 9600 bits per second:
  77. Serial.begin(115200);
  78.  
  79. while (!Serial) {
  80. ; // wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.
  81. }
  82. //motor setup
  83. pinMode(IN1, OUTPUT);
  84. pinMode(IN2, OUTPUT);
  85. pinMode(IN3, OUTPUT);
  86. pinMode(IN4, OUTPUT);
  87. attachInterrupt(digitalPinToInterrupt(m1enc1), updateMotorA , RISING);
  88. attachInterrupt(digitalPinToInterrupt(m2enc1), updateMotorB , RISING);
  89.  
  90. // imu setup
  91. Wire.begin();
  92. Wire.setClock(400000); //Increase I2C data rate to 400kHz
  93. myIMU.begin();
  94. myIMU.enableGameRotationVector(1); //Send data update every 50ms
  95.  
  96. // Now set up two tasks to run independently.
  97. xTaskCreate(
  98. TaskReadIMU
  99. , (const portCHAR *)"Blink" // A name just for humans
  100. , 2000 // This stack size can be checked & adjusted by reading the Stack Highwater
  101. , NULL
  102. , 1 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
  103. , NULL );
  104.  
  105. xTaskCreate(
  106. TaskMoveRobot
  107. , (const portCHAR *) "AnalogRead"
  108. , 2000 // Stack size
  109. , NULL
  110. , 2 // Priority
  111. , NULL );
  112.  
  113. // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
  114.  
  115. }
  116.  
  117. void loop()
  118. {
  119. // Empty. Things are done in Tasks.
  120. }
  121.  
  122. /*--------------------------------------------------*/
  123. /*---------------------- Tasks ---------------------*/
  124. /*--------------------------------------------------*/
  125.  
  126. void TaskReadIMU(void *pvParameters) // This is a task.
  127. {
  128. (void) pvParameters;
  129.  
  130.  
  131. // initialize digital LED_BUILTIN on pin 13 as an output.
  132.  
  133. for (;;) // A Task shall never return or exit.
  134. {
  135. if (myIMU.dataAvailable() == true)
  136. {
  137. float quatI = myIMU.getQuatI();
  138. float quatJ = myIMU.getQuatJ();
  139. float quatK = myIMU.getQuatK();
  140. float quatReal = myIMU.getQuatReal();
  141. float quatRadianAccuracy = myIMU.getQuatRadianAccuracy();
  142. myQuat.i = quatI;
  143. myQuat.j = quatJ;
  144. myQuat.k = quatK;
  145. myQuat.real = quatReal;
  146. eul = getAngles(myQuat);
  147. robotHeading = getHeading();
  148. }
  149. }
  150. }
  151.  
  152. void TaskMoveRobot(void *pvParameters) // This is a task.
  153. {
  154. (void) pvParameters;
  155. pinMode(LED_BUILTIN, OUTPUT);
  156. bool ranOnce = false;
  157. for (;;)
  158. {
  159. if (ranOnce == false) {
  160. vTaskDelay( 1000 / portTICK_PERIOD_MS );
  161. }
  162. ranOnce = true;
  163. turnLeftXDegrees(90);
  164. //Serial.println(robotHeading);
  165. vTaskDelay( 2000 / portTICK_PERIOD_MS );
  166. //vTaskDelay(1); // one tick delay (15ms) in between reads for stability
  167. }
  168. }
  169.  
  170.  
  171. // ----------------------------------------------------- IMU -----------------------------------------------------
  172.  
  173. float getHeading() {
  174. angle = eul.yaw;
  175.  
  176.  
  177. if (angle >= 0 && angle < headingOffset) {
  178.  
  179. return (360 - headingOffset + eul.yaw);
  180.  
  181. } else if (angle >= 0) {
  182.  
  183.  
  184. return (angle - headingOffset);
  185. } else {
  186. angle = 180 + (180 - abs((eul.yaw)));
  187.  
  188.  
  189. return (angle - headingOffset);
  190. }
  191.  
  192.  
  193. }
  194.  
  195. void getHeadingOffset() {
  196. if (gotOffset == false) {
  197.  
  198. angle = eul.yaw;
  199. if (angle != 0) {
  200. angle = eul.yaw;
  201. if (angle >= 0) {
  202. headingOffset = angle;
  203. } else {
  204. headingOffset = 180 + (180 - abs((eul.yaw)));
  205. }
  206. gotOffset = true;
  207. delay(1000);
  208. }
  209. }
  210. }
  211.  
  212. // Return the Euler angle structure from a Quaternion structure
  213. Euler getAngles(Quat q) {
  214.  
  215. Euler ret_val;
  216. float x; float y;
  217.  
  218. /* YAW */
  219. x = 2 * ((q.i * q.j) + (q.real * q.k));
  220. y = square(q.real) - square(q.k) - square(q.j) + square(q.i);
  221. ret_val.yaw = degrees(atan2(y, x));
  222.  
  223. /* PITCH */
  224. ret_val.pitch = degrees(asin(-2 * (q.i * q.k - q.j * q.real)));
  225.  
  226. /* ROLL */
  227. x = 2 * ((q.j * q.k) + (q.i * q.real));
  228. y = square(q.real) + square(q.k) - square(q.j) - square(q.i);
  229. ret_val.roll = degrees(atan2(y , x));
  230.  
  231. return ret_val;
  232.  
  233. }
  234. //----------------------------------------------------------------------------------------------------------
  235.  
  236. // ----------------------------------------------------- MOTORS -----------------------------------------------------
  237. void setStatesAndSpeed(int in1Speed, int in2Speed, int in3Speed, int in4Speed) {
  238. analogWrite(IN1, in1Speed);
  239. analogWrite(IN2, in2Speed);
  240. analogWrite(IN3, in3Speed);
  241. analogWrite(IN4, in4Speed);
  242. }
  243.  
  244. void moveForward(int leftSpeed, int rightSpeed) {
  245.  
  246. setStatesAndSpeed(0, leftSpeed, 0, rightSpeed);
  247. }
  248.  
  249. void moveBackwards(int leftSpeed, int rightSpeed) {
  250.  
  251. setStatesAndSpeed(leftSpeed, 0, rightSpeed, 0);
  252. }
  253.  
  254. void turnLeftXDegrees(int angleToTurn) {
  255. float targetAngle = 0;
  256. float initialAngle = eul.yaw;
  257. //Serial.println(robotHeading);
  258. if (robotHeading - angleToTurn < 0) {
  259.  
  260. targetAngle = (360 - angleToTurn) + robotHeading;
  261. Serial.print(eul.yaw);
  262. Serial.print("\t");
  263. Serial.print(robotHeading);
  264. Serial.print("\t");
  265. Serial.print(angleToTurn);
  266. Serial.print("\t");
  267. Serial.println(targetAngle);
  268. while ( robotHeading < targetAngle) {
  269. turnRight(turnSpeed, turnSpeed);
  270. vTaskDelay(1);
  271. Serial.print(eul.yaw);
  272. Serial.print("\t");
  273. Serial.print(robotHeading);
  274. Serial.print("\t");
  275. Serial.print(angleToTurn);
  276. Serial.print("\t");
  277. Serial.println(targetAngle);
  278. }
  279. while (robotHeading > targetAngle) {
  280. turnRight(turnSpeed, turnSpeed);
  281. vTaskDelay(1);
  282. Serial.print(eul.yaw);
  283. Serial.print("\t");
  284. Serial.print(robotHeading);
  285. Serial.print("\t");
  286. Serial.print(angleToTurn);
  287. Serial.print("\t");
  288. Serial.println(targetAngle);
  289. }
  290. Serial.println("success");
  291. return;
  292.  
  293. Serial.println("3");
  294. } else {
  295. targetAngle = robotHeading - 90;
  296.  
  297. }
  298. }
  299.  
  300. void turnRightXDegrees(int angleToTurn) {
  301. float targetAngle = 0;
  302. Serial.println("hello");
  303. Serial.print(eul.yaw);
  304. Serial.print("\t");
  305. if (eul.yaw > 0) {
  306. if (eul.yaw + angleToTurn > 180) {
  307.  
  308. Serial.println("1");
  309. targetAngle = (-180 + ((eul.yaw + angleToTurn) - 180)) - 0.01;
  310. Serial.println(targetAngle);
  311. while (eul.yaw > targetAngle) {
  312. Serial.print("moving right+ \t");
  313. Serial.print(targetAngle);
  314. Serial.print("\t");
  315. Serial.println(eul.yaw);
  316. turnRight(turnSpeed, turnSpeed);
  317. vTaskDelay(1);
  318. }
  319.  
  320. stopMoving();
  321. return;
  322. } else {
  323. targetAngle = eul.yaw + angleToTurn;
  324. Serial.println("2");
  325. while (eul.yaw < (targetAngle)) {
  326. Serial.print("moving right- \t");
  327. Serial.print(targetAngle);
  328. Serial.print("\t");
  329. Serial.println(eul.yaw);
  330. turnRight(turnSpeed, turnSpeed);
  331. vTaskDelay(1);
  332. }
  333. stopMoving();
  334. return;
  335. }
  336. } else { // eul.yaw negative
  337. targetAngle = eul.yaw + angleToTurn;
  338. Serial.println("3");
  339. while (eul.yaw < targetAngle) {
  340. Serial.print("moving right-2 \t");
  341. Serial.print(targetAngle);
  342. Serial.print("\t");
  343. Serial.println(eul.yaw);
  344. turnRight(turnSpeed, turnSpeed);
  345. vTaskDelay(1);
  346. }
  347. stopMoving();
  348. return;
  349. }
  350. }
  351.  
  352. void turnLeft(int leftSpeed, int rightSpeed) {
  353. setStatesAndSpeed(0, leftSpeed, rightSpeed, 0);
  354. }
  355.  
  356. void turnRight(int leftSpeed, int rightSpeed) {
  357. setStatesAndSpeed(leftSpeed, 0, 0, rightSpeed);
  358. }
  359. void stopMoving() {
  360. setStatesAndSpeed(255, 255, 255, 255);
  361. }
  362. void printEncoders() {
  363. Serial.print(leftEnc);
  364. Serial.print("\t");
  365. Serial.println(rightEnc);
  366. }
  367.  
  368. void updateMotorA() {
  369. leftEnc++;
  370. }
  371.  
  372. void updateMotorB() {
  373. rightEnc++;
  374. }
  375.  
  376. //----------------------------------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement