-
Notifications
You must be signed in to change notification settings - Fork 1
/
meArm.cpp
121 lines (101 loc) · 3.2 KB
/
meArm.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
#include <Arduino.h>
#include "ik.h"
#include "meArm.h"
#include <Servo.h>
bool setup_servo (ServoInfo& svo, const int n_min, const int n_max,
const float a_min, const float a_max)
{
float n_range = n_max - n_min;
float a_range = a_max - a_min;
// Must have a non-zero angle range
if(a_range == 0) return false;
// Calculate gain and zero
svo.gain = n_range / a_range;
svo.zero = n_min - svo.gain * a_min;
// Set limits
svo.n_min = n_min;
svo.n_max = n_max;
return true;
}
int angle2pwm (const ServoInfo& svo, const float angle)
{
float pwm = 0.5f + svo.zero + svo.gain * angle;
return int(pwm);
}
//Full constructor with calibration data
meArm::meArm(int sweepMinBase, int sweepMaxBase, float angleMinBase, float angleMaxBase,
int sweepMinShoulder, int sweepMaxShoulder, float angleMinShoulder, float angleMaxShoulder,
int sweepMinElbow, int sweepMaxElbow, float angleMinElbow, float angleMaxElbow,
int sweepMinGripper, int sweepMaxGripper, float angleMinGripper, float angleMaxGripper) {
//calroutine();
setup_servo(_svoBase, sweepMinBase, sweepMaxBase, angleMinBase, angleMaxBase);
setup_servo(_svoShoulder, sweepMinShoulder, sweepMaxShoulder, angleMinShoulder, angleMaxShoulder);
setup_servo(_svoElbow, sweepMinElbow, sweepMaxElbow, angleMinElbow, angleMaxElbow);
setup_servo(_svoGripper, sweepMinGripper, sweepMaxGripper, angleMinGripper, angleMaxGripper);
}
void meArm::begin(int pinBase, int pinShoulder, int pinElbow, int pinGripper) {
_pinBase = pinBase;
_pinShoulder = pinShoulder;
_pinElbow = pinElbow;
_pinGripper = pinGripper;
_base.attach(_pinBase);
_shoulder.attach(_pinShoulder);
_elbow.attach(_pinElbow);
_gripper.attach(_pinGripper);
goDirectlyTo(0, 100, 50);
openGripper();
}
//Set servos to reach a certain point directly without caring how we get there
void meArm::goDirectlyTo(float x, float y, float z) {
float radBase,radShoulder,radElbow;
if (solve(x, y, z, radBase, radShoulder, radElbow)) {
_base.write(angle2pwm(_svoBase,radBase));
_shoulder.write(angle2pwm(_svoShoulder,radShoulder));
_elbow.write(angle2pwm(_svoElbow,radElbow));
_x = x; _y = y; _z = z;
}
}
//Travel smoothly from current point to another point
int meArm::gotoPoint(float x, float y, float z) {
//Starting points - current pos
float x0 = _x;
float y0 = _y;
float z0 = _z;
float dist = sqrt((x0-x)*(x0-x)+(y0-y)*(y0-y)+(z0-z)*(z0-z));
int step = 2;
for (int i = 0; i<dist; i+= step) {
goDirectlyTo(x0 + (x-x0)*i/dist, y0 + (y-y0) * i/dist, z0 + (z-z0) * i/dist);
delay(50);
if(digitalRead(7)==LOW){
return 1;
}
}
goDirectlyTo(x, y, z);
delay(50);
return 0;
}
//Check to see if possible
bool meArm::isReachable(float x, float y, float z) {
float radBase,radShoulder,radElbow;
return (solve(x, y, z, radBase, radShoulder, radElbow));
}
//Grab something
void meArm::openGripper() {
_gripper.write(90);
delay(300);
}
//Let go of something
void meArm::closeGripper() {
_gripper.write(150);
delay(300);
}
//Current x, y and z
float meArm::getX() {
return _x;
}
float meArm::getY() {
return _y;
}
float meArm::getZ() {
return _z;
}