Control system of Delta-robot BMSTU 2018

Dependencies:   AccelStepper mbed-STM32F103C8T6 mbed

Committer:
yuliyasm
Date:
Wed Jun 20 08:12:18 2018 +0000
Revision:
1:2bfb79a5ed38
Parent:
0:1825dad3704f
final

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yuliyasm 0:1825dad3704f 1 //X-300Y22.5Z-300\r\n - пример команды управления
yuliyasm 0:1825dad3704f 2 #include "stm32f103c8t6.h"
yuliyasm 0:1825dad3704f 3 #include "mbed.h"
yuliyasm 0:1825dad3704f 4 #include "AccelStepper.h"
yuliyasm 0:1825dad3704f 5 #include <ctype.h>
yuliyasm 0:1825dad3704f 6
yuliyasm 0:1825dad3704f 7 const float r = 25; // end effector
yuliyasm 0:1825dad3704f 8 const float R = 80; // base
yuliyasm 0:1825dad3704f 9 const float l = 225.5;
yuliyasm 0:1825dad3704f 10 const float L = 100;
yuliyasm 0:1825dad3704f 11 const int q = 8; // микрошаг
yuliyasm 0:1825dad3704f 12
yuliyasm 0:1825dad3704f 13 #define pi 3.14159
yuliyasm 0:1825dad3704f 14 #define cos120 -0.5
yuliyasm 0:1825dad3704f 15 #define sin120 0.866
yuliyasm 0:1825dad3704f 16 #define tg30 0.57735
yuliyasm 0:1825dad3704f 17 #define MAXP 500 // предельные координаты
yuliyasm 0:1825dad3704f 18
yuliyasm 0:1825dad3704f 19 bool parseXYZ(char* m, float* A);
yuliyasm 0:1825dad3704f 20 float readNum(char* m, int i);
yuliyasm 0:1825dad3704f 21 bool delta_calcInverse(float* A, float* B);
yuliyasm 0:1825dad3704f 22 void MotorsInit();
yuliyasm 0:1825dad3704f 23 void Rx_interrupt();
yuliyasm 0:1825dad3704f 24
yuliyasm 0:1825dad3704f 25 PinName stp[3] = {PB_15,PA_8,PA_9};
yuliyasm 0:1825dad3704f 26 PinName dir[3] = {PB_12,PB_13,PB_14};
yuliyasm 0:1825dad3704f 27 AccelStepper axis1(1, stp[0], dir[0]);
yuliyasm 0:1825dad3704f 28 AccelStepper axis2(1, stp[1], dir[1]);
yuliyasm 0:1825dad3704f 29 AccelStepper axis3(1, stp[2], dir[2]);
yuliyasm 0:1825dad3704f 30 AccelStepper Motors[3] = {axis1, axis2, axis3};
yuliyasm 1:2bfb79a5ed38 31 DigitalIn zero1(PA_15);
yuliyasm 1:2bfb79a5ed38 32 DigitalIn zero2(PA_12);
yuliyasm 1:2bfb79a5ed38 33 DigitalIn zero3(PA_11);
yuliyasm 0:1825dad3704f 34 DigitalIn zero[3] = {zero1, zero2, zero3};
yuliyasm 0:1825dad3704f 35 DigitalOut myled(LED1);
yuliyasm 0:1825dad3704f 36 DigitalOut enb(PA_10);
yuliyasm 0:1825dad3704f 37 Timer t;
yuliyasm 0:1825dad3704f 38 Serial pc(PB_10, PB_11);
yuliyasm 0:1825dad3704f 39
yuliyasm 0:1825dad3704f 40 ////////////////////////////////////////////////////////////////////////////////////
yuliyasm 0:1825dad3704f 41 int main()
yuliyasm 0:1825dad3704f 42 {
yuliyasm 0:1825dad3704f 43 confSysClock(); //Configure system clock (72MHz HSE clock, 48MHz USB clock)
yuliyasm 0:1825dad3704f 44 t.start();
yuliyasm 0:1825dad3704f 45 pc.baud(9600);
yuliyasm 0:1825dad3704f 46 pc.attach(&Rx_interrupt, Serial::RxIrq);
yuliyasm 0:1825dad3704f 47 pc.printf("Hello\r\n");
yuliyasm 0:1825dad3704f 48 MotorsInit();
yuliyasm 0:1825dad3704f 49
yuliyasm 0:1825dad3704f 50 while(1) {
yuliyasm 0:1825dad3704f 51 for (int i = 0; i < 3; i++)
yuliyasm 0:1825dad3704f 52 Motors[i].run();
yuliyasm 0:1825dad3704f 53 if (Motors[0].distanceToGo() == 0 && Motors[1].distanceToGo() == 0 && Motors[2].distanceToGo() == 0)
yuliyasm 0:1825dad3704f 54 myled = 1;
yuliyasm 0:1825dad3704f 55 }
yuliyasm 0:1825dad3704f 56 }
yuliyasm 0:1825dad3704f 57 ///////////////////////////////////////////////////////////////////////////////////
yuliyasm 0:1825dad3704f 58
yuliyasm 0:1825dad3704f 59 void MotorsInit()
yuliyasm 0:1825dad3704f 60 {
yuliyasm 0:1825dad3704f 61 enb = 0;
yuliyasm 0:1825dad3704f 62 myled = 0;
yuliyasm 0:1825dad3704f 63
yuliyasm 0:1825dad3704f 64 for (int i = 0; i < 3; i++) {
yuliyasm 0:1825dad3704f 65 Motors[i].setMinPulseWidth (100);
yuliyasm 0:1825dad3704f 66 Motors[i].setMaxSpeed (500);
yuliyasm 0:1825dad3704f 67 Motors[i].setAcceleration (100);
yuliyasm 0:1825dad3704f 68 Motors[i].moveTo(-90*q/1.8);
yuliyasm 0:1825dad3704f 69 }
yuliyasm 1:2bfb79a5ed38 70 while(Motors[0].distanceToGo() || Motors[1].distanceToGo() || Motors[2].distanceToGo()) {
yuliyasm 0:1825dad3704f 71 for (int i = 0; i < 3; i++) {
yuliyasm 0:1825dad3704f 72 if(zero[i] != 0)
yuliyasm 1:2bfb79a5ed38 73 Motors[i].run();
yuliyasm 0:1825dad3704f 74 else
yuliyasm 0:1825dad3704f 75 Motors[i].moveTo(Motors[i].currentPosition());
yuliyasm 0:1825dad3704f 76 }
yuliyasm 0:1825dad3704f 77 }
yuliyasm 0:1825dad3704f 78 for (int i = 0; i < 3; i++) {
yuliyasm 0:1825dad3704f 79 Motors[i].stop();
yuliyasm 0:1825dad3704f 80 Motors[i].setCurrentPosition(0);
yuliyasm 1:2bfb79a5ed38 81 Motors[i].setMaxSpeed (2000);
yuliyasm 1:2bfb79a5ed38 82 Motors[i].setAcceleration (500);
yuliyasm 0:1825dad3704f 83 }
yuliyasm 0:1825dad3704f 84 myled = 1;
yuliyasm 0:1825dad3704f 85 pc.printf("Ready\r\n\r\n");
yuliyasm 0:1825dad3704f 86 }
yuliyasm 0:1825dad3704f 87
yuliyasm 0:1825dad3704f 88
yuliyasm 0:1825dad3704f 89 bool parseXYZ(char* m, float* A)
yuliyasm 0:1825dad3704f 90 {
yuliyasm 0:1825dad3704f 91 for(int i = 0; i < 32; i++) {
yuliyasm 0:1825dad3704f 92 if (m[i] == '\n' || m[i] == '\r')
yuliyasm 0:1825dad3704f 93 break;
yuliyasm 0:1825dad3704f 94 /////////////////////////////////
yuliyasm 0:1825dad3704f 95 if (m[i] == 'X') {
yuliyasm 0:1825dad3704f 96 i++;
yuliyasm 0:1825dad3704f 97 A[0] = readNum(m, i);
yuliyasm 0:1825dad3704f 98 }
yuliyasm 0:1825dad3704f 99 ////////////////////////////////
yuliyasm 0:1825dad3704f 100 if (m[i] == 'Y') {
yuliyasm 0:1825dad3704f 101 i++;
yuliyasm 0:1825dad3704f 102 A[1] = readNum(m, i);
yuliyasm 0:1825dad3704f 103 }
yuliyasm 0:1825dad3704f 104 //////////////////////////////////
yuliyasm 0:1825dad3704f 105 if (m[i] == 'Z') {
yuliyasm 0:1825dad3704f 106 i++;
yuliyasm 0:1825dad3704f 107 A[2] = readNum(m, i);
yuliyasm 0:1825dad3704f 108 }
yuliyasm 0:1825dad3704f 109 }
yuliyasm 0:1825dad3704f 110 for(int i = 0; i < 3; i++) { // проверка на адекватность
yuliyasm 0:1825dad3704f 111 if ((A[i] <= -MAXP) || (A[i] >= MAXP))
yuliyasm 0:1825dad3704f 112 return false;
yuliyasm 0:1825dad3704f 113 }
yuliyasm 0:1825dad3704f 114 return true;
yuliyasm 0:1825dad3704f 115 }
yuliyasm 0:1825dad3704f 116
yuliyasm 0:1825dad3704f 117 float readNum(char* m, int i)
yuliyasm 0:1825dad3704f 118 {
yuliyasm 0:1825dad3704f 119 char buff[10] = "";
yuliyasm 0:1825dad3704f 120 int n = 0;
yuliyasm 0:1825dad3704f 121 while ((isdigit(m[i]) || m[i] == '.' || m[i] == '-') && n < 9) {
yuliyasm 0:1825dad3704f 122 buff[n] = m[i];
yuliyasm 0:1825dad3704f 123 i++;
yuliyasm 0:1825dad3704f 124 n++;
yuliyasm 0:1825dad3704f 125 }
yuliyasm 0:1825dad3704f 126 buff[n] = '\0';
yuliyasm 0:1825dad3704f 127 if (n == 0)
yuliyasm 0:1825dad3704f 128 return (MAXP);
yuliyasm 0:1825dad3704f 129 return(atof(buff));
yuliyasm 0:1825dad3704f 130 }
yuliyasm 0:1825dad3704f 131
yuliyasm 0:1825dad3704f 132
yuliyasm 0:1825dad3704f 133 bool delta_calcAngleYZ(float x0, float y0, float z0, float &theta)
yuliyasm 0:1825dad3704f 134 {
yuliyasm 0:1825dad3704f 135 float y1 = -R; // f/2 * tg 30
yuliyasm 0:1825dad3704f 136 y0 = y0-r; // shift center to edge
yuliyasm 0:1825dad3704f 137 // z = a + b*y
yuliyasm 0:1825dad3704f 138 float a = (x0*x0 + y0*y0 + z0*z0 + L*L - l*l - y1*y1) / (2 * z0);
yuliyasm 0:1825dad3704f 139 float b = (y1 - y0) / z0;
yuliyasm 0:1825dad3704f 140 // discriminant
yuliyasm 0:1825dad3704f 141 float D = -(a + b * y1)*(a + b * y1) + L*L * (b*b + 1);
yuliyasm 0:1825dad3704f 142 if (D < 0) return false; // non-existing point
yuliyasm 0:1825dad3704f 143 float yj = (y1 - a * b - sqrt(D)) / (b*b + 1); // choosing outer point
yuliyasm 0:1825dad3704f 144 float zj = a + b * yj;
yuliyasm 0:1825dad3704f 145 theta = atan(-zj / (y1 - yj)) + ((yj > y1) ? pi : 0);
yuliyasm 0:1825dad3704f 146 theta = 180*theta/pi;
yuliyasm 0:1825dad3704f 147 return true;
yuliyasm 0:1825dad3704f 148 }
yuliyasm 0:1825dad3704f 149
yuliyasm 0:1825dad3704f 150 bool delta_calcInverse(float* A, float* B)
yuliyasm 0:1825dad3704f 151 {
yuliyasm 0:1825dad3704f 152 if (A[2] > 0)
yuliyasm 0:1825dad3704f 153 return false;
yuliyasm 0:1825dad3704f 154 float x0 = A[0];
yuliyasm 0:1825dad3704f 155 float y0 = A[1];
yuliyasm 0:1825dad3704f 156 float z0 = A[2];
yuliyasm 0:1825dad3704f 157 int status = delta_calcAngleYZ(x0, y0, z0, B[0]);
yuliyasm 0:1825dad3704f 158 if (status) {
yuliyasm 0:1825dad3704f 159 x0 = A[0]*cos120 + A[1]*sin120;
yuliyasm 0:1825dad3704f 160 y0 = A[1]*cos120 - A[0]*sin120;
yuliyasm 0:1825dad3704f 161 z0 = A[2];
yuliyasm 0:1825dad3704f 162 status = delta_calcAngleYZ(x0, y0, z0, B[1]);
yuliyasm 0:1825dad3704f 163 } // rotate coords to +120 deg
yuliyasm 0:1825dad3704f 164 if (status) {
yuliyasm 0:1825dad3704f 165 x0 = A[0]*cos120 - A[1]*sin120;
yuliyasm 0:1825dad3704f 166 y0 = A[1]*cos120 + A[0]*sin120;
yuliyasm 0:1825dad3704f 167 z0 = A[2];
yuliyasm 0:1825dad3704f 168 status = delta_calcAngleYZ(x0, y0, z0, B[2]);
yuliyasm 0:1825dad3704f 169 } // rotate coords to -120 deg
yuliyasm 0:1825dad3704f 170 return status;
yuliyasm 0:1825dad3704f 171 }
yuliyasm 0:1825dad3704f 172
yuliyasm 0:1825dad3704f 173 void Rx_interrupt()
yuliyasm 0:1825dad3704f 174 {
yuliyasm 0:1825dad3704f 175 char message[32] = "";
yuliyasm 0:1825dad3704f 176 pc.scanf("%[^\n]s", message);
yuliyasm 0:1825dad3704f 177 strcat(message, "\n");
yuliyasm 0:1825dad3704f 178 pc.printf("%s", message);
yuliyasm 0:1825dad3704f 179
yuliyasm 0:1825dad3704f 180 float point[3] = {MAXP, MAXP, MAXP};
yuliyasm 0:1825dad3704f 181 float angles[3] = {0, 0, 0};
yuliyasm 0:1825dad3704f 182
yuliyasm 0:1825dad3704f 183 bool p = parseXYZ(message, point);
yuliyasm 0:1825dad3704f 184 if(p == false) {
yuliyasm 0:1825dad3704f 185 pc.printf("Parse fail\r\n");
yuliyasm 0:1825dad3704f 186 return;
yuliyasm 0:1825dad3704f 187 }
yuliyasm 0:1825dad3704f 188 pc.printf("Point: %.2f ", point[0]);
yuliyasm 0:1825dad3704f 189 pc.printf("%.2f ", point[1]);
yuliyasm 0:1825dad3704f 190 pc.printf("%.2f\r\n", point[2]);
yuliyasm 0:1825dad3704f 191 p = delta_calcInverse(point, angles);
yuliyasm 0:1825dad3704f 192 if(p == false) {
yuliyasm 0:1825dad3704f 193 pc.printf("Kinematic fail\r\n");
yuliyasm 0:1825dad3704f 194 return;
yuliyasm 0:1825dad3704f 195 }
yuliyasm 0:1825dad3704f 196 pc.printf("Angle: ");
yuliyasm 0:1825dad3704f 197 for (int i = 0; i < 3; i++) {
yuliyasm 0:1825dad3704f 198 pc.printf("%.2f ", angles[i]);
yuliyasm 0:1825dad3704f 199 Motors[i].moveTo(int(angles[i]*q/1.8));
yuliyasm 0:1825dad3704f 200 }
yuliyasm 0:1825dad3704f 201 myled = 0;
yuliyasm 0:1825dad3704f 202 pc.printf("\r\nSuccess!\r\n\r\n");
yuliyasm 0:1825dad3704f 203 return;
yuliyasm 0:1825dad3704f 204 }