RIT VEXU Core API
Toggle main menu visibility
Loading...
Searching...
No Matches
lift.h
1
#pragma once
2
3
#include "vex/vex.h"
4
#include "core/math/controls/pid.h"
5
#include <atomic>
6
#include <map>
7
#include <vector>
8
9
using namespace
std;
10
18
template
<
typename
T>
class
Lift
{
19
public
:
27
struct
lift_cfg_t
{
28
double
up_speed, down_speed;
29
double
softstop_up, softstop_down;
30
31
PID
lift_pid;
32
};
33
55
Lift
(vex::motor_group &lift_motors,
lift_cfg_t
&lift_cfg, map<T, double> &setpoint_map, vex::limit *homing_switch = NULL)
56
: lift_motors(lift_motors), cfg(lift_cfg), lift_pid(cfg.lift_pid_cfg), setpoint_map(setpoint_map),
57
homing_switch(homing_switch) {
58
59
is_async =
true
;
60
setpoint = 0;
61
/*
62
* Create a background task that is constantly updating the lift PID, if requested.
63
* Set once, and forget.
64
*/
65
vex::task t(
66
[](
void
*ptr) {
67
Lift
&lift = *((
Lift
*)ptr);
68
69
while
(
true
) {
70
if
(lift.
get_async
())
71
lift.
hold
();
72
73
vexDelay(50);
74
}
75
76
return
0;
77
},
78
this
);
79
}
80
89
void
control_continuous
(
bool
up_ctrl,
bool
down_ctrl) {
90
static
vex::timer tmr;
91
92
double
cur_pos = 0;
93
94
// Check if there's a hook for a custom sensor. If not, use the motors.
95
if
(get_sensor == NULL)
96
cur_pos = lift_motors.position(vex::rev);
97
else
98
cur_pos = get_sensor();
99
100
if
(up_ctrl && cur_pos < cfg.softstop_up) {
101
lift_motors.spin(vex::directionType::fwd, cfg.up_speed, vex::volt);
102
setpoint = cur_pos + .3;
103
104
// std::cout << "DEBUG OUT: UP " << setpoint << ", " << tmr.time(sec) << ", " << cfg.down_speed << "\n";
105
106
// Disable the PID while going UP.
107
is_async =
false
;
108
}
else
if
(down_ctrl && cur_pos > cfg.softstop_down) {
109
// Lower the lift slowly, at a rate defined by down_speed
110
if
(setpoint > cfg.softstop_down)
111
setpoint = setpoint - (tmr.time(vex::sec) * cfg.down_speed);
112
// std::cout << "DEBUG OUT: DOWN " << setpoint << ", " << tmr.time(sec) << ", " << cfg.down_speed << "\n";
113
is_async =
true
;
114
}
else
{
115
// Hold the lift at the last setpoint
116
is_async =
true
;
117
}
118
119
tmr.reset();
120
}
121
130
void
control_manual
(
bool
up_btn,
bool
down_btn,
int
volt_up,
int
volt_down) {
131
static
bool
down_hold =
false
;
132
static
bool
init =
true
;
133
134
// Allow for setting position while still calling this function
135
if
(init || up_btn || down_btn) {
136
init =
false
;
137
is_async =
false
;
138
}
139
140
double
rev = lift_motors.position(vex::rotationUnits::rev);
141
142
if
(rev < cfg.softstop_down && down_btn)
143
down_hold =
true
;
144
else
if
(!down_btn)
145
down_hold =
false
;
146
147
if
(up_btn && rev < cfg.softstop_up)
148
lift_motors.spin(vex::directionType::fwd, volt_up, vex::voltageUnits::volt);
149
else
if
(down_btn && rev > cfg.softstop_down && !down_hold)
150
lift_motors.spin(vex::directionType::rev, volt_down, vex::voltageUnits::volt);
151
else
152
lift_motors.spin(vex::directionType::fwd, 0, vex::voltageUnits::volt);
153
}
154
166
void
control_setpoints
(
bool
up_step,
bool
down_step, vector<T> pos_list) {
167
// Make sure inputs are only processed on the rising edge of the button
168
static
bool
up_last = up_step, down_last = down_step;
169
170
bool
up_rising = up_step && !up_last;
171
bool
down_rising = down_step && !down_last;
172
173
up_last = up_step;
174
down_last = down_step;
175
176
static
int
cur_index = 0;
177
178
// Avoid an index overflow. Shouldn't happen unless the user changes pos_list between calls.
179
if
(cur_index >= pos_list.size())
180
cur_index = pos_list.size() - 1;
181
182
// Increment or decrement the index of the list, bringing it up or down.
183
if
(up_rising && cur_index < (pos_list.size() - 1))
184
cur_index++;
185
else
if
(down_rising && cur_index > 0)
186
cur_index--;
187
188
// Set the lift to hold the position in the background with the PID loop
189
set_position
(pos_list[cur_index]);
190
is_async =
true
;
191
}
192
201
bool
set_position
(T pos) {
202
this->setpoint = setpoint_map[pos];
203
is_async =
true
;
204
205
return
(lift_pid.get_target() == this->setpoint) && lift_pid.is_on_target();
206
}
207
214
bool
set_setpoint
(
double
val) {
215
this->setpoint = val;
216
return
(lift_pid.get_target() == this->setpoint) && lift_pid.is_on_target();
217
}
218
220
double
get_setpoint
() {
return
this->setpoint; }
221
226
void
hold
() {
227
lift_pid.set_target(setpoint);
228
// std::cout << "DEBUG OUT: SETPOINT " << setpoint << "\n";
229
230
if
(get_sensor != NULL)
231
lift_pid.update(get_sensor());
232
else
233
lift_pid.update(lift_motors.position(vex::rev));
234
235
// std::cout << "DEBUG OUT: ROTATION " << lift_motors.rotation(rev) << "\n\n";
236
237
lift_motors.spin(vex::fwd, lift_pid.get(), vex::volt);
238
}
239
244
void
home
() {
245
static
vex::timer tmr;
246
tmr.reset();
247
248
while
(tmr.time(vex::sec) < 3) {
249
lift_motors.spin(vex::directionType::rev, 6, vex::volt);
250
251
if
(homing_switch == NULL && lift_motors.current(vex::currentUnits::amp) > 1.5)
252
break
;
253
else
if
(homing_switch != NULL && homing_switch->pressing())
254
break
;
255
}
256
257
if
(reset_sensor != NULL)
258
reset_sensor();
259
260
lift_motors.resetPosition();
261
lift_motors.stop();
262
}
263
265
bool
get_async
() {
return
is_async; }
266
272
void
set_async
(
bool
val) { this->is_async = val; }
273
283
void
set_sensor_function
(
double
(*fn_ptr)(
void
)) { this->get_sensor = fn_ptr; }
284
291
void
set_sensor_reset
(
void
(*fn_ptr)(
void
)) { this->reset_sensor = fn_ptr; }
292
293
private
:
294
vex::motor_group &lift_motors;
295
lift_cfg_t &cfg;
296
PID
lift_pid;
297
map<T, double> &setpoint_map;
298
vex::limit *homing_switch;
299
300
atomic<double> setpoint;
301
atomic<bool> is_async;
302
303
double (*get_sensor)(void) = NULL;
304
void (*reset_sensor)(void) = NULL;
305
};
Lift::set_sensor_function
void set_sensor_function(double(*fn_ptr)(void))
Definition
lift.h:283
Lift::set_setpoint
bool set_setpoint(double val)
Definition
lift.h:214
Lift::get_async
bool get_async()
Definition
lift.h:265
Lift::set_sensor_reset
void set_sensor_reset(void(*fn_ptr)(void))
Definition
lift.h:291
Lift::control_setpoints
void control_setpoints(bool up_step, bool down_step, vector< T > pos_list)
Definition
lift.h:166
Lift::set_async
void set_async(bool val)
Definition
lift.h:272
Lift::hold
void hold()
Definition
lift.h:226
Lift::set_position
bool set_position(T pos)
Definition
lift.h:201
Lift::home
void home()
Definition
lift.h:244
Lift::Lift
Lift(vex::motor_group &lift_motors, lift_cfg_t &lift_cfg, map< T, double > &setpoint_map, vex::limit *homing_switch=NULL)
Definition
lift.h:55
Lift::control_manual
void control_manual(bool up_btn, bool down_btn, int volt_up, int volt_down)
Definition
lift.h:130
Lift::get_setpoint
double get_setpoint()
Definition
lift.h:220
Lift::control_continuous
void control_continuous(bool up_ctrl, bool down_ctrl)
Definition
lift.h:89
PID
Definition
pid.h:20
Lift::lift_cfg_t
Definition
lift.h:27
include
core
subsystems
lift.h
Generated by
1.18.0