JMotor
Loading...
Searching...
No Matches
JMotorControllerClosed.h
Go to the documentation of this file.
1#ifndef J_MOTOR_CONTROLLER_CLOSED_H
2#define J_MOTOR_CONTROLLER_CLOSED_H
3#include "Derivs_Limiter.h"
5#include "JEncoder/JEncoder.h"
7#include "JMotorController.h"
9#include <Arduino.h>
13class JMotorControllerClosed : public virtual JMotorController, public virtual JMotorControllerBase {
14protected:
18
19 float velLimit;
21 float setVal;
23 bool open;
24 unsigned long lastRunMicros;
27 bool posMode;
35 float time;
36
37public:
41 Derivs_Limiter posSetpointSmoother;
43
56 JMotorControllerClosed(JMotorDriver& _driver, JMotorCompensator& _compensator, JEncoder& _encoder, JControlLoop& _controlLoop, float _velLimit = INFINITY, float _accelLimit = INFINITY, float _distFromSetpointLimit = 1, bool _preventGoingWrongWay = true, float _maxStoppingDecel = 2)
57 : driver(_driver)
58 , compensator(_compensator)
59 , encoder(_encoder)
60 , posSetpointSmoother(Derivs_Limiter(_velLimit, _accelLimit))
61 , controlLoop(_controlLoop)
62 {
63 posSetpointSmoother.setPreventGoingWrongWay(_preventGoingWrongWay);
64 posSetpointSmoother.setMaxStoppingDecel(_maxStoppingDecel);
66 velLimit = max(_velLimit, (float)0.0);
67 accelLimit = max(_accelLimit, (float)0.0);
68 open = true;
69 setVal = 0;
70 lastRunMicros = micros();
71 posMode = false;
72 posSetpoint = 0;
74 smoothed = false;
78 velSetpoint = 0;
80 distFromSetpointLimit = max(_distFromSetpointLimit, (float)0.0);
81 time = 0;
82 }
83 void run()
84 {
85 encoder.run();
86 time = (micros() - lastRunMicros) / 1000000.0;
87 if (time == 0)
88 return;
89 lastRunMicros = micros();
90 if (getEnable()) {
91 if (open) {
93 if (posSetpointSmoother.getPreventGoingWrongWay() && velSetpointTarget != 0 && velSetpoint != 0 && ((velSetpointTarget > 0) != (velSetpoint > 0))) {
94 velSetpoint = 0;
95 }
97 }
101
102 if (!encoder.hasDirection()) {
103 if (setVal > 0)
104 encoder.setRev(false);
105 if (setVal < 0)
106 encoder.setRev(true);
107 }
108
112 } else { // closed loop
113 if (posMode) {
114 if (smoothed) { // setPosTarget
115 posSetpointSmoother.setPosition(posSetpoint);
120 posSetpointSmoother.setPosition(posSetpoint);
121 }
122 } else { // setPosSetpoint
124 // nothing to do here, posSetpoint was set
125 }
126 } else { // posDelta
128 if (posSetpointSmoother.getPreventGoingWrongWay() && posDeltaSetpointTarget != 0 && posDeltaSetpoint != 0 && ((posDeltaSetpointTarget > 0) != (posDeltaSetpoint > 0))) {
129 posDeltaSetpoint = 0; // prevent going wrong way
130 }
134 }
138 }
139 // MAKE MOTOR GO TO posSetpoint, by setting velSetpointTarget
140
142
144
145 velSetpoint = velSetpointTarget; // open loop uses velSetpointTarget and velsetpoint for acceleration, but closed loop has posDeltaSetpointTarget and posDeltaSetpoint, so just set them equal
146
148
149 if (!encoder.hasDirection()) {
150 if (setVal > 0)
151 encoder.setRev(false);
152 if (setVal < 0)
153 encoder.setRev(true);
154 }
155
157 } // end of closed loop mode
158 } // enabled
159 }
160
161 void setVel(float vel, bool _run = true)
162 {
163 setPosDelta(vel, false, false);
165 if (_run)
166 run();
167 }
168 void setVelTarget(float vel, bool _run = true)
169 {
170 setAccelPosDelta(vel, false, false);
172 if (_run)
173 run();
174 }
175 bool setPosTarget(float _posTarget, bool _run = true)
176 {
178 if (open)
180 open = false;
181 if (posMode == false) {
182 posSetpointSmoother.resetTime();
183 posSetpointSmoother.setVelocity(velSetpoint);
184 }
185 bool ret = posSetpointSmoother.getTarget() != _posTarget;
186 posMode = true;
187 smoothed = true;
188 posSetpointSmoother.setTarget(_posTarget);
189 if (_run)
190 run();
191 return ret; // did the target change?
192 }
193 bool setPosTargetStallable(float _posTarget, bool _run = true)
194 {
196 if (open)
198 open = false;
199 if (posMode == false) {
200 posSetpointSmoother.resetTime();
201 posSetpointSmoother.setVelocity(velSetpoint);
202 }
203 bool ret = posSetpointSmoother.getTarget() != _posTarget;
204 posMode = true;
205 smoothed = true;
206 posSetpointSmoother.setTarget(_posTarget);
207 if (_run)
208 run();
209 return ret; // did the target change?
210 }
211 bool setPosSetpoint(float _posSetpoint, bool _run = true)
212 {
213 if (open)
215 open = false;
216 posMode = true;
217 smoothed = false;
218 bool ret = posSetpoint != _posSetpoint;
219 posSetpoint = _posSetpoint;
220 if (_run)
221 run();
222 return ret; // did the setpoint change?
223 }
224 bool setPosDelta(float _posDelta, bool _run = true, bool _resetPos = false)
225 {
226 if (open)
228 open = false;
229 posMode = false;
231 bool ret = posDeltaSetpointTarget != _posDelta;
232 posDeltaSetpoint = _posDelta;
233 posDeltaSetpointTarget = _posDelta;
234 if (_resetPos)
235 resetPos();
236 if (_run)
237 run();
238 return ret; // did the setting change?
239 }
240 void setAccelPosDelta(float _posDelta, bool _run = true, bool _resetPos = false)
241 {
242 if (open == true || posMode == true) {
244 }
245 if (open)
247 open = false;
248 posMode = false;
250 posDeltaSetpointTarget = _posDelta;
251 if (_resetPos)
252 resetPos();
253 if (_run)
254 run();
255 }
261 void setOpenVel(float vel, bool _run = true)
262 {
263 velSetpointTarget = vel;
264 velSetpoint = vel;
265 posMode = false;
266 open = true;
267 if (_run)
268 run();
269 }
275 void setOpenVelTarget(float vel, bool _run = true)
276 {
277 velSetpointTarget = vel;
278 open = true;
279 posMode = false;
280 if (_run)
281 run();
282 }
283
285 {
286 return (velSetpoint - encoder.getVel()) / velSetpoint;
287 }
288
290 {
291 if (!open && posMode && smoothed) {
292 return posSetpointSmoother.getTarget();
293 }
294 return posSetpoint;
295 }
296
298 {
299 return posSetpoint;
300 }
301
303 {
304 if (open)
305 return velSetpointTarget;
306 else
308 }
309
311 {
312 return posDeltaSetpoint;
313 }
314
316 {
317 return lastPosSetpoint;
318 }
319
320 float getTime()
321 {
322 return time;
323 }
324
326 {
328 }
329
330 void setDistFromSetpointLimit(float _distFromSetpointLimit)
331 {
332 distFromSetpointLimit = max(_distFromSetpointLimit, (float)0.0);
333 }
334
341 {
342 return velSetpoint;
343 }
344 float getVel()
345 {
346 return encoder.getVel();
347 }
348 float getPos()
349 {
350 return encoder.getPos();
351 }
352 float resetPos()
353 {
354 float oldDist = encoder.getPos();
356 posSetpoint -= oldDist;
357 lastPosSetpoint -= oldDist;
358 posSetpointSmoother.setPosition(0);
359 posSetpointSmoother.setTarget(posSetpointSmoother.getTarget() - oldDist);
360
361 return oldDist;
362 }
364 {
365 return posMode;
366 }
368 {
369 return !open;
370 }
371 void setAccelLimit(float _accelLimit)
372 {
373 accelLimit = max(_accelLimit, (float)0.0);
374 posSetpointSmoother.setAccelAndDecelLimits(accelLimit, accelLimit);
375 }
376 void setVelLimit(float _velLimit)
377 {
378 velLimit = max(_velLimit, (float)0.0);
379 posSetpointSmoother.setVelLimit(velLimit);
380 }
381
383 {
384 return accelLimit;
385 }
387 {
388 return velLimit;
389 }
390
391 void setPreventGoingWrongWay(bool _preventGoingWrongWay)
392 {
393 posSetpointSmoother.setPreventGoingWrongWay(_preventGoingWrongWay);
394 }
395
396 void setMaxStoppingDecel(float _maxStoppingDecel)
397 {
398 posSetpointSmoother.setMaxStoppingDecel(_maxStoppingDecel);
399 }
400
402 {
403 return setVal;
404 }
405
406 bool setEnable(bool _enable)
407 {
408 if (_enable == false) {
409 posSetpointSmoother.setVelocity(0);
410 velSetpoint = 0;
411 }
412 if (_enable == true && !getEnable()) { // enabling
413 lastRunMicros = micros();
415 posSetpointSmoother.resetTime();
416 }
417 return driver.setEnable(_enable);
418 }
419 void setMaxDriverRangeAmount(float _driverRangeAmount)
420 {
421 compensator.setMaxDriverRangeAmount(_driverRangeAmount);
422 }
423
425 {
426 return driverInRange;
427 }
428
429 bool enable()
430 {
431 return setEnable(true);
432 }
433
434 bool disable()
435 {
436 return setEnable(false);
437 }
438
443
448
450 {
451 return driver.getEnable();
452 }
453
454 float getMaxVel()
455 {
456 return compensator.getMaxVel();
457 }
458
459 float getMinVel()
460 {
461 return compensator.getMinVel();
462 }
463};
464#endif
interface for control loop used by JMotorControllerClosed
Definition JControlLoop.h:7
virtual void resetTime()=0
virtual float calc(JMotorControllerClosed *controller)=0
defines common interface for JEncoder
Definition JEncoder.h:33
virtual void setRev(bool _rev)
empty function for directionless encoders to override
Definition JEncoder.h:38
virtual void run()
if an encoder needs to have some code called each loop (like absolute encoder polling encoder and cal...
virtual float getPos()
returns how far the encoder has turned from the zero position converted to distance
virtual float getVel()
calculates velocity in distance per second where distance was set by setdistPerCountFactor()
virtual bool hasDirection()
can this encoder measure direction or just speed
virtual long zeroCounter()
reset the counter of how far the encoder has turned
This class defines a common interface for converting from speed to driver input. It should compensate...
Definition JMotorCompensator.h:9
virtual float getMaxVel()
How fast of a motor speed setting would get adjusted to full motor power.
void setDriverRange(float _driverRange)
set what value makes the driver output 100% of supply voltage
Definition JMotorCompensator.h:19
virtual float compensate(float val)
calculate
virtual float getMinVel()
Slowest speed motor can go.
void setMaxDriverRangeAmount(float _driverRangeAmount)
set what fraction of driverRange can be used
Definition JMotorCompensator.h:27
float getMaxDriverRangeAmount()
get what fraction of driverRange can be used
Definition JMotorCompensator.h:64
This class defines a common interface for classes which control velocity of a motor controlled by a J...
Definition JMotorControllerBase.h:7
closed loop (uses encoder) motor controller
Definition JMotorControllerClosed.h:13
void setDistFromSetpointLimit(float _distFromSetpointLimit)
Definition JMotorControllerClosed.h:330
bool isClosedLoop()
Definition JMotorControllerClosed.h:367
float accelLimit
Definition JMotorControllerClosed.h:20
float posSetpoint
Definition JMotorControllerClosed.h:28
float getVelLimit()
returns value of velLimit
Definition JMotorControllerClosed.h:386
float getAccelLimit()
returns value of accelLimit
Definition JMotorControllerClosed.h:382
float getPosTarget()
get position set as target (for smoothed position setting mode)
Definition JMotorControllerClosed.h:289
bool driverInRange
Definition JMotorControllerClosed.h:22
float getDriverMinRange()
if getDriverSetVal goes below this, isDriverInRange will go false
Definition JMotorControllerClosed.h:439
float velSetpointTarget
Definition JMotorControllerClosed.h:26
bool isPosModeNotVelocity()
true if controller is in position target mode, false if in velocity mode
Definition JMotorControllerClosed.h:363
float getMaxVel()
How fast of a motor speed setting would get adjusted to full motor power.
Definition JMotorControllerClosed.h:454
unsigned long lastRunMicros
Definition JMotorControllerClosed.h:24
void run()
update driver
Definition JMotorControllerClosed.h:83
void setOpenVelTarget(float vel, bool _run=true)
set velocity without closed loop control, with limited acceleration
Definition JMotorControllerClosed.h:275
void setOpenVel(float vel, bool _run=true)
set velocity without closed loop control
Definition JMotorControllerClosed.h:261
float posDeltaSetpoint
Definition JMotorControllerClosed.h:30
float getLastPosSetpoint()
Definition JMotorControllerClosed.h:315
bool disable()
disable motor controller
Definition JMotorControllerClosed.h:434
bool setPosTarget(float _posTarget, bool _run=true)
set target position (motor drives towards position, following acceleration profile)
Definition JMotorControllerClosed.h:175
JEncoder & encoder
Definition JMotorControllerClosed.h:17
bool smoothed
Definition JMotorControllerClosed.h:29
float velSetpoint
Definition JMotorControllerClosed.h:25
bool isDriverInRange()
true if motor driver is being set to within its range, false if driver is at a maximum
Definition JMotorControllerClosed.h:424
bool setEnable(bool _enable)
change whether motor controller is enabled
Definition JMotorControllerClosed.h:406
void setVelLimit(float _velLimit)
set maximum motor speed
Definition JMotorControllerClosed.h:376
void setPreventGoingWrongWay(bool _preventGoingWrongWay)
Definition JMotorControllerClosed.h:391
void setMaxDriverRangeAmount(float _driverRangeAmount)
set what fraction of driverRange can be used
Definition JMotorControllerClosed.h:419
float getPos()
get what position the motor is currently at
Definition JMotorControllerClosed.h:348
float setVal
Definition JMotorControllerClosed.h:21
bool setPosDelta(float _posDelta, bool _run=true, bool _resetPos=false)
alternative method for setting velocity that uses setPosSetpoint
Definition JMotorControllerClosed.h:224
bool getEnable()
is the controller enabled
Definition JMotorControllerClosed.h:449
void setVelTarget(float vel, bool _run=true)
set target velocity for controller (acceleration limited)
Definition JMotorControllerClosed.h:168
float resetPos()
reset what position the controller thinks it's in
Definition JMotorControllerClosed.h:352
float time
Definition JMotorControllerClosed.h:35
void setMaxStoppingDecel(float _maxStoppingDecel)
Definition JMotorControllerClosed.h:396
bool open
Definition JMotorControllerClosed.h:23
JControlLoop & controlLoop
Definition JMotorControllerClosed.h:42
float getVelTarget()
get target velocity for controller
Definition JMotorControllerClosed.h:302
float getDriverMaxRange()
if getDriverSetVal exceeds this, isDriverInRange will go false
Definition JMotorControllerClosed.h:444
float getPosSetpoint()
get position controller is currently trying to get to
Definition JMotorControllerClosed.h:297
float getDistFromSetpointLimit()
Definition JMotorControllerClosed.h:325
float getDriverSetVal()
returns the value the motor driver is being set to
Definition JMotorControllerClosed.h:401
void setVel(float vel, bool _run=true)
set velocity for controller
Definition JMotorControllerClosed.h:161
float getTime()
Definition JMotorControllerClosed.h:320
float getVelSetpoint()
returns how fast the motor driver is told to move
Definition JMotorControllerClosed.h:340
JMotorCompensator & compensator
Definition JMotorControllerClosed.h:16
float lastPosSetpoint
Definition JMotorControllerClosed.h:34
bool enable()
enable motor controller
Definition JMotorControllerClosed.h:429
float getVel()
get current velocity of motor
Definition JMotorControllerClosed.h:344
float getPosDeltaSetpoint()
Definition JMotorControllerClosed.h:310
JMotorDriver & driver
Definition JMotorControllerClosed.h:15
bool posMode
Definition JMotorControllerClosed.h:27
Derivs_Limiter posSetpointSmoother
Definition JMotorControllerClosed.h:41
float velLimit
Definition JMotorControllerClosed.h:19
float posDeltaSetpointTarget
Definition JMotorControllerClosed.h:31
bool setPosSetpoint(float _posSetpoint, bool _run=true)
set position for motor to drive towards position as fast as possible (setpoint for control loop if av...
Definition JMotorControllerClosed.h:211
float getMinVel()
slowest speed motor can go
Definition JMotorControllerClosed.h:459
float getSpeedError()
Definition JMotorControllerClosed.h:284
void setAccelPosDelta(float _posDelta, bool _run=true, bool _resetPos=false)
Definition JMotorControllerClosed.h:240
bool setPosTargetStallable(float _posTarget, bool _run=true)
Definition JMotorControllerClosed.h:193
JMotorControllerClosed(JMotorDriver &_driver, JMotorCompensator &_compensator, JEncoder &_encoder, JControlLoop &_controlLoop, float _velLimit=INFINITY, float _accelLimit=INFINITY, float _distFromSetpointLimit=1, bool _preventGoingWrongWay=true, float _maxStoppingDecel=2)
Constructor for closed loop motor controller.
Definition JMotorControllerClosed.h:56
void setAccelLimit(float _accelLimit)
set maximum rate that motor speed can be changed at
Definition JMotorControllerClosed.h:371
float distFromSetpointLimit
Definition JMotorControllerClosed.h:33
bool limitSetpointDistFromCurrent
Definition JMotorControllerClosed.h:32
This class defines a common interface for classes which control velocity and position of a motor cont...
Definition JMotorController.h:8
defines common interface for all types of JMotorDrivers
Definition JMotorDriver.h:10
virtual bool set(float val)
set motor power
virtual bool setEnable(bool _enable)
use to enable or disable a motor, and sets up pin states
virtual float getMaxRange()
high end of the range
virtual float getMinRange()
low end of the range
virtual bool getEnable()
get the enable state of the driver