Advertisement
Guest User

Untitled

a guest
Jan 19th, 2018
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.53 KB | None | 0 0
  1. #include <RotaryEncoder.h>
  2. #include <SPI.h>
  3. #include "RF24.h"
  4. #include <TimerOne.h>
  5. #include <math.h>
  6. #include <PID_v1.h>
  7.  
  8. void Odometry();
  9.  
  10. // Variables for Odometry
  11. float Wheel_L_size = 78.7;
  12. float Wheel_R_size = 78.7;
  13. //jak nie dojeżdża to zwiększyc wartosc Encoder_scope_ , jak przejeżdza to zmniejszyć
  14. //float Encoder_scope_L = 970.5;
  15. //float Encoder_scope_R = 960.5;
  16. float Encoder_scope_L = 960;
  17. float Encoder_scope_R = 960;
  18. float Distance_between_wheels = 137;
  19.  
  20. // Definition of left and right encoder PINs
  21. RotaryEncoder encoder_L(A4, A5);
  22. RotaryEncoder encoder_R(A3, A2);
  23.  
  24. // RF communication PIN declarations
  25. RF24 radio(7,8);
  26.  
  27. // PID controller
  28. double kp_L = 5 , ki_L = 1 , kd_L = 0.01 ,input_L = 0, output_L = 0, setpoint_L = 0; // modify kp, ki and kd for optimal performance
  29. double kp_R = 5 , ki_R = 1 , kd_R = 0.01 ,input_R = 0, output_R = 0, setpoint_R = 0; // modify kp, ki and kd for optimal performance
  30. PID myPID_L(&input_L, &output_L, &setpoint_L, kp_L, ki_L, kd_L, DIRECT); // if motor will only run at full speed try 'REVERSE' instead of 'DIRECT'
  31. PID myPID_R(&input_R, &output_R, &setpoint_R, kp_R, ki_R, kd_R, DIRECT); // if motor will only run at full speed try 'REVERSE' instead of 'DIRECT'
  32.  
  33.  
  34. // Motor left PIN declaration
  35. int dir1PinA = 2;
  36. int dir2PinA = 9;
  37. int speedPinA = 5; // Needs to be a PWM pin to be able to control motor speed == 5
  38.  
  39. // Motor right PIN declaration
  40. int dir1PinB = 4;
  41. int dir2PinB = 10;
  42. int speedPinB = 3; // Needs to be a PWM pin to be able to control motor speed == 3
  43.  
  44. // Motors rotate speed
  45. int Motors_Rotate_Speed = 20;
  46.  
  47. // Motors line speed
  48. int Motors_Line_Speed = 20;
  49.  
  50. // Innterrupt variables( Odometry and motors PID/Speed variables )
  51. float X_Global = 400;
  52. float Y_Global = 400;
  53. //float X_Global = 0;
  54. //float Y_Global = 0;
  55. float Angle_Global=0;
  56. float Angle_Desired = 0;
  57. float Angle_Desired_temp=Angle_Desired;
  58. boolean Flag_Angle=true;
  59. long int ticks2_L = 0;
  60. long int ticks2_R = 0;
  61. long temp_L = 0;
  62. long temp_R = 0;
  63. int Sp_L=0;
  64. int Sp_R=0;
  65.  
  66.  
  67. // Function initializing RF24 module
  68. void init_NRF(){
  69. radio.begin();
  70. radio.setPALevel(RF24_PA_LOW);
  71. radio.setDataRate(RF24_1MBPS);
  72. radio.setCRCLength(RF24_CRC_16);
  73. radio.setPayloadSize(32);
  74. radio.setChannel(1);
  75. radio.setAutoAck(true);
  76. radio.openWritingPipe(0x314e6f6465);
  77. radio.openReadingPipe(1,0x324e6f6465);
  78. radio.startListening();
  79. }
  80.  
  81. // Function setting up motors speed
  82. void motors_L_R(int Speed_L,int Speed_R){
  83.  
  84. Sp_L=Speed_L;
  85. Sp_R=Speed_R;
  86.  
  87. }
  88.  
  89. // Function calculating global X and Y position based on encoder values and also actually setting up motors speed
  90. // This function is called every 0,0015 sec
  91. void Odometry(){
  92.  
  93. if (Sp_L >= 0){
  94. temp_L+=Sp_L;
  95. }
  96. else if (Sp_L < 0){
  97. temp_L-=-Sp_L;
  98. }
  99.  
  100. if (Sp_R >= 0){
  101. temp_R+=Sp_R;
  102. }
  103. else if (Sp_R < 0){
  104. temp_R-=-Sp_R;
  105. }
  106.  
  107. setpoint_R=temp_R/99.3; // modify division to fit motor and encoder characteristics
  108. setpoint_L=temp_L/100; // modify division to fit motor and encoder characteristics
  109.  
  110. input_R=encoder_R.getPosition();
  111. input_L=encoder_L.getPosition();
  112.  
  113. myPID_R.Compute(); // calculate new output
  114. myPID_L.Compute(); // calculate new output
  115.  
  116.  
  117. if (output_L >= 0){
  118. digitalWrite(dir1PinA, HIGH);
  119. digitalWrite(dir2PinA, LOW);
  120. analogWrite(speedPinA,output_L);
  121. }
  122. else {
  123. digitalWrite(dir1PinA, LOW);
  124. digitalWrite(dir2PinA, HIGH);
  125. analogWrite(speedPinA,-output_L);
  126. }
  127.  
  128. if (output_R >= 0){
  129. digitalWrite(dir1PinB, HIGH);
  130. digitalWrite(dir2PinB, LOW);
  131. analogWrite(speedPinB, output_R);
  132. }
  133. else {
  134. digitalWrite(dir1PinB, LOW);
  135. digitalWrite(dir2PinB, HIGH);
  136. analogWrite(speedPinB,-output_R);
  137. }
  138.  
  139.  
  140. long int ticks1_L=input_L;
  141. long int ticks1_R=input_R;
  142.  
  143. long int L_ticks=ticks1_L - ticks2_L;
  144. long int R_ticks=ticks1_R - ticks2_R;
  145.  
  146. ticks2_L=ticks1_L;
  147. ticks2_R=ticks1_R;
  148.  
  149. float L_mm= (float)L_ticks * ( ( Wheel_L_size * PI ) / Encoder_scope_L);
  150. float R_mm= (float)R_ticks *( ( Wheel_R_size * PI ) / Encoder_scope_R);
  151.  
  152. float MM=( L_mm + R_mm ) / 2;
  153.  
  154. if(Flag_Angle){
  155. Angle_Global += ((L_mm - R_mm)/ Distance_between_wheels )*(180.0/PI);
  156.  
  157.  
  158. while ( Angle_Global < 0 || Angle_Global >= 360){
  159. if ( Angle_Global < 0){
  160. Angle_Global = Angle_Global + 360;
  161. }
  162. if ( Angle_Global >= 360){
  163. Angle_Global = Angle_Global - 360;
  164. }
  165. }
  166.  
  167. while ( Angle_Desired_temp < 0 || Angle_Desired_temp >= 360){
  168. if ( Angle_Desired_temp < 0){
  169. Angle_Desired_temp = Angle_Desired_temp + 360;
  170. }
  171. if ( Angle_Desired_temp >= 360){
  172. Angle_Desired_temp = Angle_Desired_temp - 360;
  173. }
  174. }
  175.  
  176.  
  177.  
  178.  
  179. }else{
  180. Y_Global += MM*cos( Angle_Global /(180/PI));
  181. X_Global += MM*sin( Angle_Global /(180/PI));
  182. }
  183. }
  184.  
  185.  
  186. void setup() {
  187.  
  188. // Initialize serial communication @ 115200 baud:
  189. Serial.begin(57600);
  190.  
  191. init_NRF();
  192.  
  193. Timer1.initialize(1500);
  194. Timer1.attachInterrupt(Odometry);
  195.  
  196. myPID_L.SetMode(AUTOMATIC);
  197. myPID_L.SetSampleTime(1);
  198. myPID_L.SetOutputLimits(-255, 255);
  199.  
  200. myPID_R.SetMode(AUTOMATIC);
  201. myPID_R.SetSampleTime(1);
  202. myPID_R.SetOutputLimits(-255, 255);
  203.  
  204. pinMode(dir1PinA,OUTPUT);
  205. pinMode(dir2PinA,OUTPUT);
  206. pinMode(speedPinA,OUTPUT);
  207. pinMode(dir1PinB,OUTPUT);
  208. pinMode(dir2PinB,OUTPUT);
  209. pinMode(speedPinB,OUTPUT);
  210.  
  211. // You may have to modify the next 2 lines if using other pins than A2 and A3
  212. PCICR |= (1 << PCIE1); // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
  213. PCMSK1 |= (1 << PCINT10) | (1 << PCINT11) |(1 << PCINT12)|(1 << PCINT13); // This enables the interrupt for pin 2, 3, 4 and 5.
  214.  
  215. }
  216.  
  217. // The Interrupt Service Routine for Pin Change Interrupt 1
  218. // This routine will only be called on any signal change on A2, A3, A4 and A5: exactly where we need to check.
  219.  
  220. ISR(PCINT1_vect) {
  221. encoder_L.tick(); // just call tick() to check the state.
  222. encoder_R.tick();
  223. }
  224.  
  225.  
  226. void gotoXY( int X_Desired, int Y_Desired, int Speed ){
  227.  
  228. Flag_Angle=true; //uruchom flagę przy ruchu
  229. Motors_Rotate_Speed = Speed;
  230. Motors_Line_Speed = Speed;
  231.  
  232. float X_Diff = ( X_Desired - X_Global );
  233. float Y_Diff = ( Y_Desired - Y_Global );
  234.  
  235. //Calculating desired angle based on global angle
  236.  
  237. Angle_Desired = atan2( X_Diff , Y_Diff )*(180/PI);
  238.  
  239. if ( Angle_Desired < 0){
  240. Angle_Desired = 360 + Angle_Desired ;
  241. }
  242.  
  243. float add, subtract;
  244.  
  245. //////Rotating based on desired angle and global angle/////
  246.  
  247. if ( Angle_Desired > Angle_Global ) {
  248. add = Angle_Desired - Angle_Global ;
  249. subtract = Angle_Global + 360 - Angle_Desired ;
  250. }
  251. else{
  252. add = 360 - Angle_Global + Angle_Desired ;
  253. subtract = Angle_Global - Angle_Desired ;
  254. }
  255.  
  256. Angle_Desired_temp=Angle_Desired;
  257.  
  258. if ( subtract > add ){
  259. if(add>=90){
  260. Angle_Desired_temp+=6;
  261. }
  262. }
  263. if ( subtract < add ){
  264. if(subtract>=90){
  265. Angle_Desired_temp-=4;
  266. }
  267. }
  268.  
  269.  
  270. while ( abs( Angle_Desired_temp - Angle_Global ) > 0.6){
  271.  
  272. Serial.print(Angle_Desired_temp);
  273. Serial.print(" ");
  274. Serial.print(Angle_Global);
  275. Serial.print(" ");
  276.  
  277. if ( subtract > add ){
  278.  
  279. Serial.println(Y_Global);
  280. motors_L_R( Motors_Rotate_Speed, -Motors_Rotate_Speed );
  281. }
  282. else {
  283. Serial.println(Y_Global);
  284. motors_L_R( -Motors_Rotate_Speed , Motors_Rotate_Speed );
  285. }
  286. }
  287. Serial.println(Y_Global);
  288. motors_L_R(0,0);
  289.  
  290. if ( subtract > add ){
  291. if(add>=90){
  292. Angle_Global-=6;
  293. }
  294. }
  295. if ( subtract < add ){
  296. if(subtract>=90){
  297. Angle_Global+=4;
  298. }
  299. }
  300.  
  301. Flag_Angle=false; //koniec obrotu uruchom flage
  302.  
  303.  
  304. //////////////Movement/////////////
  305.  
  306.  
  307. if ( Angle_Desired != 0 && Angle_Desired != 90 && Angle_Desired != 180 && Angle_Desired != 270){
  308.  
  309. if ( X_Desired >= X_Global && Y_Desired >= Y_Global ){ // Angle_Desired ... 0 --> 90
  310. while ( X_Global <= X_Desired || Y_Global <= Y_Desired ){
  311. Serial.println(Y_Global);
  312. motors_L_R( Motors_Line_Speed , Motors_Line_Speed );
  313. }
  314. }
  315.  
  316. else if ( X_Desired >= X_Global && Y_Desired < Y_Global ){ // Angle_Desired ... 90 --> 180
  317. while ( X_Global <= X_Desired || Y_Global >= Y_Desired ){
  318.  
  319.  
  320. Serial.print(X_Global);
  321. Serial.print(" ");
  322. Serial.println(Y_Global);
  323.  
  324. motors_L_R( Motors_Line_Speed , Motors_Line_Speed );
  325. }
  326. }
  327.  
  328. else if ( X_Desired < X_Global && Y_Desired < Y_Global ){ // Angle_Desired ... 180 --> 270
  329. while ( X_Global >= X_Desired || Y_Global >= Y_Desired ){
  330.  
  331. Serial.println(Y_Global);
  332. motors_L_R( Motors_Line_Speed , Motors_Line_Speed );
  333. }
  334. }
  335.  
  336. else if ( X_Desired < X_Global && Y_Desired >= Y_Global ){ // Angle_Desired ... 270 --> 360
  337. while ( X_Global >= X_Desired || Y_Global <= Y_Desired ){
  338.  
  339. Serial.println(Y_Global);
  340. motors_L_R( Motors_Line_Speed , Motors_Line_Speed );
  341. }
  342. }
  343.  
  344.  
  345. }
  346. else {
  347.  
  348. if ( Angle_Desired == 0){ // Angle_Desired == 0
  349. while ( Y_Global < Y_Desired ){
  350. Serial.print(X_Global);
  351. Serial.print(" ");
  352. Serial.println(Y_Global);
  353. motors_L_R( Motors_Line_Speed , Motors_Line_Speed );
  354. }
  355. }
  356.  
  357. else if ( Angle_Desired == 90){ // Angle_Desired == 90
  358. while( X_Global < X_Desired ){
  359. Serial.println(Y_Global);
  360. motors_L_R( Motors_Line_Speed , Motors_Line_Speed );
  361. }
  362. }
  363.  
  364. else if ( Angle_Desired == 180){ // Angle_Desired == 180
  365. while( Y_Global > Y_Desired ){
  366. Serial.println(Y_Global);
  367. motors_L_R( Motors_Line_Speed , Motors_Line_Speed );
  368. }
  369. }
  370.  
  371. else if ( Angle_Desired == 270){ // Angle_Desired == 270
  372. while( X_Global > X_Desired ){
  373. Serial.println(Y_Global);
  374. motors_L_R( Motors_Line_Speed , Motors_Line_Speed );
  375. }
  376. }
  377.  
  378. }
  379. ///////////END --> STOP MOTORS////////////////
  380. Serial.println(Y_Global);
  381. motors_L_R(0,0);
  382. X_Global=X_Desired;
  383. Y_Global=Y_Desired;
  384. Angle_Global=Angle_Desired;
  385. }
  386.  
  387. void loop() {
  388. gotoXY(500,500,20);
  389. gotoXY(1000,500,20);
  390. gotoXY(1000,1000,20);
  391. /*gotoXY(1500,3500,20);
  392. gotoXY(2000,3500,20);
  393. gotoXY(2500,3500,20);
  394. gotoXY(2500,3000,20);
  395. gotoXY(2500,2500,20);
  396. */
  397. /*
  398. gotoXY(0,400,20);
  399. gotoXY(800,400,20);
  400. gotoXY(600,1000,20);
  401. gotoXY(200,200,20);
  402. gotoXY(1000,1200,20);
  403. gotoXY(1300,1000,20);
  404. */
  405. /*
  406. gotoXY(200,200,20);
  407. gotoXY(200,500,20);
  408. gotoXY(0,700,20);
  409. gotoXY(300,700,20);
  410. gotoXY(600,300,20);
  411. gotoXY(1500,2000,20);
  412. */
  413.  
  414. /*
  415. gotoXY(1500,1000,20);
  416. gotoXY(1000,1000,20);
  417. gotoXY(1000,1500,20);
  418. */
  419. /*
  420. while (encoder_L.getPosition()<=Encoder_scope_L*15){
  421. Serial.println(Y_Global);
  422. motors_L_R(20,20);
  423.  
  424. }
  425. */
  426. //motors_L_R(0,0);
  427.  
  428. delay(100000);
  429. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement