-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathStudentsRobot.cpp
More file actions
236 lines (223 loc) · 7.8 KB
/
StudentsRobot.cpp
File metadata and controls
236 lines (223 loc) · 7.8 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*
* StudentsRobot.cpp
*
* Created on: Dec 28, 2018
* Author: hephaestus
*/
#include "StudentsRobot.h"
StudentsRobot::StudentsRobot(PIDMotor * motor1,
PIDMotor * motor2, PIDMotor * motor3,
Servo * servo) {
Serial.println("StudentsRobot::StudentsRobot constructor called here ");
this->servo = servo;
this->motor1 = motor1;
this->motor2 = motor2;
this->motor3 = motor3;
// Set the PID Clock gating rate. The PID must be 10 times slower than the motors update rate
motor1->myPID.sampleRateMs = 5; //
motor2->myPID.sampleRateMs = 5; //
motor3->myPID.sampleRateMs = 5; // 10khz H-Bridge, 0.1ms update, 1 ms PID
// Set default P.I.D gains
motor1->myPID.setpid(0.00015, 0, 0);
motor2->myPID.setpid(0.00015, 0, 0);
motor3->myPID.setpid(0.00015, 0, 0);
motor1->velocityPID.setpid(0.1, 0, 0);
motor2->velocityPID.setpid(0.1, 0, 0);
motor3->velocityPID.setpid(0.1, 0, 0);
// compute ratios and bounding
double motorToWheel = 3;
motor1->setOutputBoundingValues(-255, //the minimum value that the output takes (Full reverse)
255, //the maximum value the output takes (Full forward)
0, //the value of the output to stop moving
125, //a positive value subtracted from stop value to creep backward
125, //a positive value added to the stop value to creep forwards
16.0 * // Encoder CPR
50.0 * // Motor Gear box ratio
motorToWheel * // motor to wheel stage ratio
(1.0 / 360.0) * // degrees per revolution
2, // Number of edges that are used to increment the value
480, // measured max degrees per second
150 // the speed in degrees per second that the motor spins when the hardware output is at creep forwards
);
motor2->setOutputBoundingValues(-255, //the minimum value that the output takes (Full reverse)
255, //the maximum value the output takes (Full forward)
0, //the value of the output to stop moving
125, //a positive value subtracted from stop value to creep backward
125, //a positive value added to the stop value to creep forwards
16.0 * // Encoder CPR
50.0 * // Motor Gear box ratio
motorToWheel * // motor to wheel stage ratio
(1.0 / 360.0) * // degrees per revolution
2, // Number of edges that are used to increment the value
480, // measured max degrees per second
150 // the speed in degrees per second that the motor spins when the hardware output is at creep forwards
);
motor3->setOutputBoundingValues(-255, //the minimum value that the output takes (Full reverse)
255, //the maximum value the output takes (Full forward)
0, //the value of the output to stop moving
125, //a positive value subtracted from stop value to creep backward
125, //a positive value added to the stop value to creep forwards
16.0 * // Encoder CPR
50.0 * // Motor Gear box ratio
1.0 * // motor to arm stage ratio
(1.0 / 360.0) * // degrees per revolution
2, // Number of edges that are used to increment the value
1400, // measured max degrees per second
50 // the speed in degrees per second that the motor spins when the hardware output is at creep forwards
);
// Set up the line tracker
pinMode(ANALOG_SENSE_ONE, ANALOG);
pinMode(ANALOG_SENSE_TWO, ANALOG);
pinMode(H_BRIDGE_ENABLE, OUTPUT);
}
/**
* Seperate from running the motor control,
* update the state machine for running the final project code here
*/
void StudentsRobot::updateStateMachine() {
long now = millis();
switch (status) {
case StartupRobot:
//Do this once at startup
status = StartRunning;
Serial.println("StudentsRobot::updateStateMachine StartupRobot here ");
break;
case StartRunning:
Serial.println("Start Running");
digitalWrite(H_BRIDGE_ENABLE, 1);
// Start an interpolation of the motors
motor1->startInterpolationDegrees(motor1->getAngleDegrees(), 1000, SIN);
motor2->startInterpolationDegrees(motor2->getAngleDegrees(), 1000, SIN);
motor3->startInterpolationDegrees(motor3->getAngleDegrees(), 1000, SIN);
status = WAIT_FOR_MOTORS_TO_FINNISH; // set the state machine to wait for the motors to finish
nextStatus = Running; // the next status to move to when the motors finish
startTime = now + 1000; // the motors should be done in 1000 ms
nextTime = startTime + 1000; // the next timer loop should be 1000ms after the motors stop
break;
case Running:
// Set up a non-blocking 1000 ms delay
status = WAIT_FOR_TIME;
nextTime = nextTime + 1000; // ensure no timer drift by incremeting the target
// After 1000 ms, come back to this state
nextStatus = Running;
// Do something
if (!digitalRead(0))
Serial.println(
" Running State Machine " + String((now - startTime)));
break;
case WAIT_FOR_TIME:
// Check to see if enough time has elapsed
if (nextTime <= millis()) {
// if the time is up, move on to the next state
status = nextStatus;
}
break;
case WAIT_FOR_MOTORS_TO_FINNISH:
if (motor1->isInterpolationDone() && motor2->isInterpolationDone()
&& motor3->isInterpolationDone()) {
status = nextStatus;
}
break;
case Halting:
// save state and enter safe mode
Serial.println("Halting State machine");
//digitalWrite(H_BRIDGE_ENABLE, 0); // Disable and idle motors
motor3->stop();
motor2->stop();
motor1->stop();
status = Halt;
break;
case Halt:
// in safe mode
break;
}
}
/**
* This is run fast and should return fast
*
* You call the PIDMotor's loop function. This will update the whole motor control system
* This will read from the concoder and write to the motors and handle the hardware interface.
* Instead of allowing this to be called by the controller you may call these from a timer interrupt.
*/
void StudentsRobot::pidLoop() {
motor1->loop();
motor2->loop();
motor3->loop();
}
/**
* Approve
*
* @param buffer A buffer of floats containing nothing
*
* the is the event of the Approve button pressed in the GUI
*
* This function is called via coms.server() in:
* @see RobotControlCenter::fastLoop
*/
void StudentsRobot::Approve(float * buffer) {
// approve the procession to new state
Serial.println("StudentsRobot::Approve");
if (myCommandsStatus == Waiting_for_approval_to_pickup) {
myCommandsStatus = Waiting_for_approval_to_dropoff;
} else {
myCommandsStatus = Ready_for_new_task;
}
}
/**
* ClearFaults
*
* @param buffer A buffer of floats containing nothing
*
* this represents the event of the clear faults button press in the gui
*
* This function is called via coms.server() in:
* @see RobotControlCenter::fastLoop
*/
void StudentsRobot::ClearFaults(float * buffer) {
// clear the faults somehow
Serial.println("StudentsRobot::ClearFaults");
myCommandsStatus = Ready_for_new_task;
status = Running;
}
/**
* EStop
*
* @param buffer A buffer of floats containing nothing
*
* this represents the event of the EStop button press in the gui
*
* This is called whrn the estop in the GUI is pressed
* All motors shuld hault and lock in position
* Motors should not go idle and drop the plate
*
* This function is called via coms.server() in:
* @see RobotControlCenter::fastLoop
*/
void StudentsRobot::EStop(float * buffer) {
// Stop the robot immediatly
Serial.println("StudentsRobot::EStop");
myCommandsStatus = Fault_E_Stop_pressed;
status = Halting;
}
/**
* PickOrder
*
* @param buffer A buffer of floats containing the pick order data
*
* buffer[0] is the material, aluminum or plastic.
* buffer[1] is the drop off angle 25 or 45 degrees
* buffer[2] is the drop off position 1, or 2
*
* This function is called via coms.server() in:
* @see RobotControlCenter::fastLoop
*/
void StudentsRobot::PickOrder(float * buffer) {
float pickupMaterial = buffer[0];
float dropoffAngle = buffer[1];
float dropoffPosition = buffer[2];
Serial.println(
"StudentsRobot::PickOrder Recived from : " + String(pickupMaterial)
+ " " + String(dropoffAngle) + " "
+ String(dropoffPosition));
myCommandsStatus = Waiting_for_approval_to_pickup;
}