JMotor
Loading...
Searching...
No Matches
JDrivetrainControllerBasic.h
Go to the documentation of this file.
1#ifndef J_DRIVETRAIN_CONTROLLER_BASIC_H
2#define J_DRIVETRAIN_CONTROLLER_BASIC_H
4#include "JTwoDTransform.h"
5#include <Arduino.h>
10// TODO: comments
12protected:
15 unsigned long lastCalcMillis;
16
18
20
21public:
23 Derivs_Limiter XLimiter;
24 Derivs_Limiter YLimiter;
25 Derivs_Limiter ThetaLimiter;
27 JDrivetrainControllerBasic(JDrivetrain& _drivetrain, JTwoDTransform _velLimit, JTwoDTransform _accelLimit, JTwoDTransform _distError, bool _velNotPosDelta = true)
28 : drivetrain(_drivetrain)
29 , XLimiter(Derivs_Limiter(_velLimit.x, _accelLimit.x))
30 , YLimiter(Derivs_Limiter(_velLimit.y, _accelLimit.y))
31 , ThetaLimiter(Derivs_Limiter(_velLimit.theta, _accelLimit.theta))
32 , distError(_distError)
33 {
34 YLimiter.setPreventGoingWrongWay(false);
35 XLimiter.setPreventGoingWrongWay(false);
36 ThetaLimiter.setPreventGoingWrongWay(false);
37 YLimiter.setPreventGoingTooFast(true);
38 ThetaLimiter.setPreventGoingTooFast(true);
39 XLimiter.setPreventGoingTooFast(true);
40 controlled = false;
41 distMode = false;
43 velNotPosDelta = _velNotPosDelta;
44 }
45
49 void run()
50 {
51 float time = (micros() - lastCalcMillis) / 1000000.0;
52 if (lastCalcMillis == 0) {
53 time = 0;
54 lastCalcMillis = micros();
55 }
56 if (time == 0) {
57 return;
58 }
59 lastCalcMillis = micros();
60 if (getEnable()) {
61 if (controlled) {
62 if (distMode) { // go towards target position with smoothed velocity
63 YLimiter.calc();
64 ThetaLimiter.calc();
65 XLimiter.calc();
66
67 JTwoDTransform dist = getDist(); // prevent setpoint from getting to far from actual
68 YLimiter.setPosition(constrain(YLimiter.getPosition(), dist.y - distError.y, dist.y + distError.y));
69 ThetaLimiter.setPosition(constrain(ThetaLimiter.getPosition(), dist.theta - distError.theta, dist.theta + distError.theta));
70 XLimiter.setPosition(constrain(XLimiter.getPosition(), dist.x - distError.x, dist.x + distError.x));
71
72 drivetrain.setDistSetpoint({ XLimiter.getPosition(), YLimiter.getPosition(), ThetaLimiter.getPosition() }, false);
73 } else {
74 // accelerate towards velocity target
75 if (YLimiter.getVelocity() != velTarget.y) {
76 YLimiter.setVelocity(YLimiter.getVelocity() + constrain(velTarget.y - YLimiter.getVelocity(), -YLimiter.getAccelLimit() * time, YLimiter.getAccelLimit() * time));
77 }
78 if (ThetaLimiter.getVelocity() != velTarget.theta) {
79 ThetaLimiter.setVelocity(ThetaLimiter.getVelocity() + constrain(velTarget.theta - ThetaLimiter.getVelocity(), -ThetaLimiter.getAccelLimit() * time, ThetaLimiter.getAccelLimit() * time));
80 }
81 if (XLimiter.getVelocity() != velTarget.x) {
82 XLimiter.setVelocity(XLimiter.getVelocity() + constrain(velTarget.x - XLimiter.getVelocity(), -XLimiter.getAccelLimit() * time, XLimiter.getAccelLimit() * time));
83 }
84
85 YLimiter.setVelocity(constrain(YLimiter.getVelocity(), -YLimiter.getVelLimit(), YLimiter.getVelLimit()));
86 ThetaLimiter.setVelocity(constrain(ThetaLimiter.getVelocity(), -ThetaLimiter.getVelLimit(), ThetaLimiter.getVelLimit()));
87 XLimiter.setVelocity(constrain(XLimiter.getVelocity(), -XLimiter.getVelLimit(), XLimiter.getVelLimit()));
88
89 YLimiter.setVelocity(constrain(YLimiter.getVelocity(), -getMaxVel().y, getMaxVel().y));
90 ThetaLimiter.setVelocity(constrain(ThetaLimiter.getVelocity(), -getMaxVel().theta, getMaxVel().theta));
91 XLimiter.setVelocity(constrain(XLimiter.getVelocity(), -getMaxVel().x, getMaxVel().x));
92
93 if (velNotPosDelta) {
94 drivetrain.setVel({ XLimiter.getVelocity(), YLimiter.getVelocity(), ThetaLimiter.getVelocity() });
95 } else {
96 drivetrain.setDistDelta({ XLimiter.getVelocity(), YLimiter.getVelocity(), ThetaLimiter.getVelocity() });
97 }
98 }
99 }
100 }
101
102 drivetrain.run();
103 }
104
110 void moveVel(JTwoDTransform _vel, bool _run = false)
111 {
112 if (distMode || !controlled) {
113 JTwoDTransform vel = getVel();
114 YLimiter.setVelocity(vel.y);
115 ThetaLimiter.setVelocity(vel.theta);
116 XLimiter.setVelocity(vel.x);
117 }
118
119 controlled = true;
120 distMode = false;
121
122 velTarget = _vel;
123
124 if (_run)
125 run();
126 }
127
134 {
135 return XLimiter.isPosAtTarget() && YLimiter.isPosAtTarget() && ThetaLimiter.isPosAtTarget();
136 }
137
144 void moveDist(JTwoDTransform _dist, bool _run = false)
145 {
146 if (!distMode || !controlled) {
147 YLimiter.resetTime();
148 XLimiter.resetTime();
149 ThetaLimiter.resetTime();
150 JTwoDTransform vel = getVel();
151 YLimiter.setVelocity(vel.y);
152 ThetaLimiter.setVelocity(vel.theta);
153 XLimiter.setVelocity(vel.x);
154 JTwoDTransform dist = getDist();
155 YLimiter.setPosition(dist.y);
156 ThetaLimiter.setPosition(dist.theta);
157 XLimiter.setPosition(dist.x);
158 }
159 YLimiter.setTarget(_dist.y);
160 ThetaLimiter.setTarget(_dist.theta);
161 XLimiter.setTarget(_dist.x);
162
163 controlled = true;
164 distMode = true;
165
166 if (_run)
167 run();
168 }
169
170 void moveDistY(float _y, bool _run = false)
171 {
172 JTwoDTransform targ = getDist();
173 targ.y = _y;
174 moveDist(targ, _run);
175 }
176
177 void moveDistTheta(float _theta, bool _run = false)
178 {
179 JTwoDTransform targ = getDist();
180 targ.theta = _theta;
181 moveDist(targ, _run);
182 }
183
184 void moveDistX(float _x, bool _run = false)
185 {
186 JTwoDTransform targ = getDist();
187 targ.x = _x;
188 moveDist(targ, _run);
189 }
190
191 void moveDistInc(JTwoDTransform _d, bool _run = false)
192 {
193 JTwoDTransform targ = getDist();
194 targ += _d;
195 moveDist(targ, _run);
196 }
197
198 void moveDistYInc(float _y, bool _run = false)
199 {
200 JTwoDTransform targ = getDist();
201 targ.y += _y;
202 moveDist(targ, _run);
203 }
204
205 void moveDistThetaInc(float _theta, bool _run = false)
206 {
207 JTwoDTransform targ = getDist();
208 targ.theta += _theta;
209 moveDist(targ, _run);
210 }
211
212 void moveDistXInc(float _x, bool _run = false)
213 {
214 JTwoDTransform targ = getDist();
215 targ.x += _x;
216 moveDist(targ, _run);
217 }
218
220 {
221 JTwoDTransform vel = getVel(false);
222 return (vel.x == 0 && vel.y == 0 && vel.theta == 0);
223 }
224
230 {
231 return distMode;
232 }
233
239 {
240 return controlled;
241 }
242
244 {
245 if (controlled && distMode) {
246 return { XLimiter.getTarget(), YLimiter.getTarget(), ThetaLimiter.getTarget() };
247 } else {
248 return getDist();
249 }
250 }
251
253 {
254 setVelLimitY(_velLim.y);
255 setVelLimitX(_velLim.x);
256 setVelLimitTheta(_velLim.theta);
257 }
259 {
260 setAccelLimitY(_accelLim.y);
261 setAccelLimitX(_accelLim.x);
262 setAccelLimitTheta(_accelLim.theta);
263 }
264
266 {
267 return { XLimiter.getVelLimit(), YLimiter.getVelLimit(), ThetaLimiter.getVelLimit() };
268 }
269
271 {
272 return { XLimiter.getAccelLimit(), YLimiter.getAccelLimit(), ThetaLimiter.getAccelLimit() };
273 }
274
275 void setVelLimitY(float l)
276 {
277 YLimiter.setVelLimit(l);
278 }
279 void setVelLimitX(float l)
280 {
281 XLimiter.setVelLimit(l);
282 }
283 void setVelLimitTheta(float l)
284 {
285 ThetaLimiter.setVelLimit(l);
286 }
287 void setAccelLimitY(float l)
288 {
289 YLimiter.setAccelLimit(l);
290 }
291 void setAccelLimitX(float l)
292 {
293 XLimiter.setAccelLimit(l);
294 }
295 void setAccelLimitTheta(float l)
296 {
297 ThetaLimiter.setAccelLimit(l);
298 }
299
304 void setVelNotPosDelta(bool _velNotPosDelta)
305 {
306 velNotPosDelta = _velNotPosDelta;
307 }
308
310
316 void setVel(JTwoDTransform _vel, bool _run = false)
317 {
318 controlled = false;
319 drivetrain.setVel(_vel, false);
320 if (_run)
321 run();
322 }
323 void setDistSetpoint(JTwoDTransform _dist, bool _run = false)
324 {
325 controlled = false;
326 drivetrain.setDistSetpoint(_dist, false);
327 if (_run)
328 run();
329 }
330 void setDistDelta(JTwoDTransform _dist, bool _run = false)
331 {
332 controlled = false;
333 drivetrain.setDistDelta(_dist, false);
334 if (_run)
335 run();
336 }
338 {
339 JTwoDTransform dist = getDist();
340 JTwoDTransform offBy = { XLimiter.getTarget() - dist.x, YLimiter.getTarget() - dist.y, ThetaLimiter.getTarget() - dist.theta };
341
342 YLimiter.setTarget(offBy.y);
343 ThetaLimiter.setTarget(offBy.theta);
344 XLimiter.setTarget(offBy.x);
345
346 YLimiter.setPosition(YLimiter.getPosition() - dist.y);
347 ThetaLimiter.setPosition(ThetaLimiter.getPosition() - dist.theta);
348 XLimiter.setPosition(XLimiter.getPosition() - dist.x);
349
351 }
352 JTwoDTransform getVel(bool _run = false)
353 {
354 if (_run)
355 run();
356 return drivetrain.getVel(false);
357 }
358 JTwoDTransform getDist(bool _run = false)
359 {
360 if (_run)
361 run();
362 return drivetrain.getDist(false);
363 }
370 {
371 return { XLimiter.getPosition(), YLimiter.getPosition(), ThetaLimiter.getPosition() };
372 }
374 {
375 return drivetrain.getMaxVel();
376 }
377 float getMotorVel(unsigned char i)
378 {
379 return drivetrain.getMotorVel(i);
380 }
381 void setMotorVel(float vel, unsigned char i, bool _run = false)
382 {
383 drivetrain.setMotorVel(vel, i, _run);
384 }
385 void setMotorDistSetpoint(float distSetpoint, unsigned char i, bool _run = false)
386 {
387 drivetrain.setMotorDistSetpoint(distSetpoint, i, _run);
388 }
389 void setMotorDistDelta(float distDelta, unsigned char i, bool _run = false)
390 {
391 drivetrain.setMotorDistDelta(distDelta, i, _run);
392 }
393 unsigned char getNumberMotors()
394 {
396 }
397
398 bool setEnable(bool _enable)
399 {
400 if (_enable && !getEnable()) {
401 YLimiter.resetTime();
402 ThetaLimiter.resetTime();
403 XLimiter.resetTime();
404 JTwoDTransform vel = getVel();
405 YLimiter.setVelocity(vel.y);
406 ThetaLimiter.setVelocity(vel.theta);
407 XLimiter.setVelocity(vel.x);
408 JTwoDTransform dist = getDist();
409 YLimiter.setPosition(dist.y);
410 ThetaLimiter.setPosition(dist.theta);
411 XLimiter.setPosition(dist.x);
413 }
414 return drivetrain.setEnable(_enable);
415 }
416 bool enable()
417 {
418 return setEnable(true);
419 }
420 bool disable()
421 {
422 return setEnable(false);
423 }
425 {
426 return drivetrain.getEnable();
427 }
428};
429#endif
virtual bool getEnable()=0
gets the current state (enabled or disabled)
virtual void setVel(JTwoDTransform _vel, bool _run=false)=0
sets a velocity for the drivetrain to move at
virtual void run()=0
call this in loop. it calls any encoder or motor update functions
virtual bool setEnable(bool _enable)=0
enables or disables movement
virtual JTwoDTransform getMaxVel()=0
returns the approximate maximum velocity of the drivetrain, if the drivetrain is told to move at max ...
basic drivetrain controller, supports smoothed movements on each axis
Definition JDrivetrainControllerBasic.h:11
bool setEnable(bool _enable)
enables or disables movement
Definition JDrivetrainControllerBasic.h:398
bool getIsControlled()
true=velocity and acceleration is limited, false=writing directly to drivetrain
Definition JDrivetrainControllerBasic.h:238
JTwoDTransform getAccelLimit()
Definition JDrivetrainControllerBasic.h:270
JTwoDTransform distError
Definition JDrivetrainControllerBasic.h:26
void setMotorVel(float vel, unsigned char i, bool _run=false)
Definition JDrivetrainControllerBasic.h:381
void moveDistYInc(float _y, bool _run=false)
Definition JDrivetrainControllerBasic.h:198
JTwoDTransform getDistTarget()
Definition JDrivetrainControllerBasic.h:243
float getMotorVel(unsigned char i)
Definition JDrivetrainControllerBasic.h:377
void moveDistX(float _x, bool _run=false)
Definition JDrivetrainControllerBasic.h:184
void run()
run as frequently as possible
Definition JDrivetrainControllerBasic.h:49
void setAccelLimitTheta(float l)
Definition JDrivetrainControllerBasic.h:295
void setDistDelta(JTwoDTransform _dist, bool _run=false)
Definition JDrivetrainControllerBasic.h:330
void moveDistThetaInc(float _theta, bool _run=false)
Definition JDrivetrainControllerBasic.h:205
bool disable()
disables movement
Definition JDrivetrainControllerBasic.h:420
bool getEnable()
gets the current state (enabled or disabled)
Definition JDrivetrainControllerBasic.h:424
boolean isDrivetrainAtTarget()
are all the drivetrain distance Derivs_Limiters at their position targets?
Definition JDrivetrainControllerBasic.h:133
bool isVelZero()
Definition JDrivetrainControllerBasic.h:219
JTwoDTransform getVel(bool _run=false)
Definition JDrivetrainControllerBasic.h:352
Derivs_Limiter XLimiter
Definition JDrivetrainControllerBasic.h:23
void setVelLimit(JTwoDTransform _velLim)
Definition JDrivetrainControllerBasic.h:252
void moveVel(JTwoDTransform _vel, bool _run=false)
make drivetrain approach set velocity following acceleration limits
Definition JDrivetrainControllerBasic.h:110
JTwoDTransform getMaxVel()
returns the approximate maximum velocity of the drivetrain, if the drivetrain is told to move at max ...
Definition JDrivetrainControllerBasic.h:373
JDrivetrain & drivetrain
Definition JDrivetrainControllerBasic.h:22
bool distMode
Definition JDrivetrainControllerBasic.h:14
JTwoDTransform getVelLimit()
Definition JDrivetrainControllerBasic.h:265
JTwoDTransform getDistSetpoint()
returns what distances are being set as the setpoints for each axis of the drivetrain
Definition JDrivetrainControllerBasic.h:369
bool velNotPosDelta
Definition JDrivetrainControllerBasic.h:19
void setVelLimitY(float l)
Definition JDrivetrainControllerBasic.h:275
void setAccelLimit(JTwoDTransform _accelLim)
Definition JDrivetrainControllerBasic.h:258
void moveDistTheta(float _theta, bool _run=false)
Definition JDrivetrainControllerBasic.h:177
void setVel(JTwoDTransform _vel, bool _run=false)
sets drivetrain velocity immediately
Definition JDrivetrainControllerBasic.h:316
void setAccelLimitX(float l)
Definition JDrivetrainControllerBasic.h:291
JTwoDTransform getDist(bool _run=false)
Definition JDrivetrainControllerBasic.h:358
Derivs_Limiter ThetaLimiter
Definition JDrivetrainControllerBasic.h:25
unsigned char getNumberMotors()
Definition JDrivetrainControllerBasic.h:393
Derivs_Limiter YLimiter
Definition JDrivetrainControllerBasic.h:24
unsigned long lastCalcMillis
Definition JDrivetrainControllerBasic.h:15
void setMotorDistDelta(float distDelta, unsigned char i, bool _run=false)
Definition JDrivetrainControllerBasic.h:389
JDrivetrainControllerBasic(JDrivetrain &_drivetrain, JTwoDTransform _velLimit, JTwoDTransform _accelLimit, JTwoDTransform _distError, bool _velNotPosDelta=true)
Definition JDrivetrainControllerBasic.h:27
bool getDistMode()
true if going to distance target, false if velocity based
Definition JDrivetrainControllerBasic.h:229
JTwoDTransform velTarget
Definition JDrivetrainControllerBasic.h:17
void setVelLimitX(float l)
Definition JDrivetrainControllerBasic.h:279
void setAccelLimitY(float l)
Definition JDrivetrainControllerBasic.h:287
void setVelNotPosDelta(bool _velNotPosDelta)
true = uses setVel() when setting drivetrain velocity, false = uses setPosDelta() when setting drivet...
Definition JDrivetrainControllerBasic.h:304
bool controlled
Definition JDrivetrainControllerBasic.h:13
bool enable()
enables movement
Definition JDrivetrainControllerBasic.h:416
void setMotorDistSetpoint(float distSetpoint, unsigned char i, bool _run=false)
Definition JDrivetrainControllerBasic.h:385
void moveDistY(float _y, bool _run=false)
Definition JDrivetrainControllerBasic.h:170
void resetDist()
Definition JDrivetrainControllerBasic.h:337
void setVelLimitTheta(float l)
Definition JDrivetrainControllerBasic.h:283
void moveDistXInc(float _x, bool _run=false)
Definition JDrivetrainControllerBasic.h:212
void setDistSetpoint(JTwoDTransform _dist, bool _run=false)
Definition JDrivetrainControllerBasic.h:323
void moveDist(JTwoDTransform _dist, bool _run=false)
make each axis of the drivetrain go to target position, following accel and vel limits
Definition JDrivetrainControllerBasic.h:144
void moveDistInc(JTwoDTransform _d, bool _run=false)
Definition JDrivetrainControllerBasic.h:191
defines interface for controlling any ground-based drivetrain
Definition JDrivetrain.h:10
virtual void setMotorDistDelta(float distDelta, unsigned char i, bool _run=false)
virtual JTwoDTransform getVel(bool _run=false)
virtual JTwoDTransform getDist(bool _run=false)
virtual unsigned char getNumberMotors()
virtual void setMotorVel(float vel, unsigned char i, bool _run=false)
virtual void setDistDelta(JTwoDTransform _dist, bool _run=false)
virtual float getMotorVel(unsigned char i)
virtual void resetDist()
virtual void setMotorDistSetpoint(float distSetpoint, unsigned char i, bool _run=false)
virtual void setDistSetpoint(JTwoDTransform _dist, bool _run=false)
struct for storing a 2 dimensional transformation. Used for telling a drivetrain how to move.
Definition JTwoDTransform.h:9
float theta
clockwise- | counterclockwise+
Definition JTwoDTransform.h:21
float x
backwards- | forward+
Definition JTwoDTransform.h:13
float y
right- | left+
Definition JTwoDTransform.h:17