-
Notifications
You must be signed in to change notification settings - Fork 0
/
geometry.cpp
131 lines (120 loc) · 3.24 KB
/
geometry.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
* geometry.cpp
*
* Created on: Jul 15, 2015
* Author: Jacob
*/
#include "geometry.h"
Geometry::Geometry(AllegroStepper *aMot, AllegroStepper *bMot) //initialize position system
{
a_pos=b_pos=x_pos=y_pos=a_orig=b_orig=x_offset=y_offset=0;
a_mot = aMot;
b_mot = bMot;
isHomed = false;
}
//TODO: Automatic homing
void Geometry::setOrigin(float aPos, float bPos) //sets home position to specified position, also allows positioning
{
a_orig = a_pos = aPos;
b_orig = b_pos = bPos;
isHomed = true;
float* xy = abToxy(a_pos,b_pos,AB_DISTANCE);
x_pos = xy[0];
y_pos = xy[1];
x_offset = y_offset = 0;
//x_pos = y_pos = 0;
Serial.print(getRealX());
Serial.print('#');
Serial.println(getRealY());
}
bool Geometry::gotoPos(float x, float y, float vel) //go to specified position in millimeters, at specified velocity in mm/s
{
if (!isHomed) //do nothing if system not homed
return false;
//Serial.print(a_pos);
//Serial.print('-');
//Serial.println(b_pos);
float delta_x = x-x_pos;
float delta_y = y-y_pos;
float length = sqrt(delta_x*delta_x+delta_y*delta_y); //get length of path in mm
float* newAB = xyToab(x+x_offset,y+y_offset, AB_DISTANCE);
float delta_a = newAB[0]-a_pos;
float delta_b = newAB[1]-b_pos;
/*if (delta_a>A_MAX_LENGTH)
delta_a = A_MAX_LENGTH;
else if (delta_a<A_MIN_LENGTH)
delta_a = A_MIN_LENGTH;
else if (delta_b>B_MAX_LENGTH)
delta_b = B_MAX_LENGTH;
else if (delta_b<B_MIN_LENGTH)
delta_b = B_MIN_LENGTH;*/
int steps_a = delta_a * A_STEPS_PER_MM;
int steps_b = delta_b * B_STEPS_PER_MM;
long time = 1000000L*(length/vel);
//Serial.print(steps_a);
//Serial.print(':');
//Serial.print(steps_b);
//Serial.print(':');
//Serial.println(time);
move(steps_a, steps_b, time);
x_pos = x;
y_pos = y;
a_pos = newAB[0];
b_pos = newAB[1];
return true;
}
float Geometry::getX() {return x_pos;}
float Geometry::getY() {return y_pos;}
float Geometry::getRealX() {return x_pos+x_offset;}
float Geometry::getRealY() {return y_pos+y_offset;}
void Geometry::move(int aSteps,int bSteps, long us)
{
bool aDir = aSteps>0;
bool bDir = bSteps>0;
aSteps = abs(aSteps);
bSteps = abs(bSteps);
long aInt = us/aSteps;
long bInt = us/bSteps;
long curTime = micros();
long nextA = curTime+aInt;
long nextB = curTime+bInt;
while(aSteps>0 || bSteps>0)
{
curTime = micros();
if (curTime>nextA && aSteps>0)
{
a_mot->step(aDir);
nextA = curTime+aInt;
aSteps--;
//Serial.print("a:");
//Serial.println(aSteps);
}
if (curTime>nextB && bSteps>0)
{
b_mot->step(bDir);
nextB = curTime+aInt;
bSteps--;
//Serial.print("b:");
//Serial.println(bSteps);
}
}
}
void Geometry::hold()
{
a_mot->enable();
b_mot->enable();
}
float * xyToab(float x, float y, float d) //converts absolute (x,y) coordinates into (a,b) coordinates with (a=0,b=d) being the xy origin, and d being the distance between a and b
{
float* ab = new float[2];
ab[0] = sqrt(x*x+y*y);
ab[1] = sqrt((d-x)*(d-x)+y*y);
return ab;
}
float* abToxy(float a, float b, float d) //converts (a,b) coordinates into absolute (x,y) coordinates with (a=0,b=d) being the xy origin, and d being the distance between a and b
{
float* xy = new float[2];
xy[0] = (a*a-b*b+d*d)/(2*d); // find x
xy[1] = -a*sqrt(1-pow((a*a-b*b+d*d)/(2*a*d),2)); //find y
return xy;
}