# Acceleration/deceleration with mixing

8 years 8 months ago #29529471 by LROBBINS
I am helping two friends with scripting their Roboteq HDC2450 and HBL2360 controllers. In both cases they are using Throttle and Steering joystick outputs that are mixed by the controller to get Motor 1 and Motor 2 command values and both of them reported a serious controllability problem when decelerating from a forward-moving turn. Indeed, there is a problem and it applies to acceleration while turning as well as deceleration, though it was first noticed during deceleration. It derives from the fact that although the motor commands are the result of mixing the Throttle and Steering values, the mixing algorithm is not in any way applied to acceleration and deceleration rates.

It is easier to see this graphically than to explain it with words, so I have attached several graphs. The first illustrates the "normal" result of centering the stick after being in a steady forward turn. The graph contains four curves; two correspond to Motor 1(red) and Motor 2 (yellow) power as one would see them in the Roborun Run tab, and two show what the vehicle does as the result of these - these are just the result of un-mixing the motor power values to get fore/aft (green) and left/right (blue) motion. (BTW, These graphs were made in a spreadsheet, but I think it would be very useful, and rather trivial, to add the fore/aft and left/right curves to the Roborun graph choices as they give a fairly intuitive picture of the effective results under mixing.)

At the start of this graph, we are in an 18% turn with M2 power less than M1 power. When the stick is centered, both power curves decline at the same rate, and forward motion decays in parallel. Notice, however, what happens to turning motion. Turning does not stop, nor decay at all, until M2 power has gone to zero - when forward motion has already largely ceased, and fore/aft deceleration rate is halved because one motor is already stopped. If this were an automobile, I think I'd describe this as severe torque oversteer during deceleration. As these are actually high-performance wheelchairs, the result is busted doorways and perhaps busted legs.

The converse occurs if you accelerate into a turn. The vehicle will move straight forward (or back) until the inside wheel reaches its set power and only then will it start to turn. Imagine trying to go around an obstacle with this kind of behavior!

The second graph shows that, if instead of just applying constant deceleration values to both motors, we use the un-mixed fore/aft and left/right results to bias the deceleration rates, we can get rid of this problem. Here, deceleration rate of the inside wheel is reduced and that of the outside wheel is increased, but because the turn rate decays over time, so does this bias.

Now, the power curves are not parallel straight lines but converge, and fore/aft motion declines linearly even at the end. Most importantly, instead of continuing to turn at a constant rate until forward motion has nearly stopped, the vehicle also straightens out.

As shown in the next two graphs, we can get an even snappier steering response by over-weighting the biasing of deceleration rates.

In both of these, initial fore/aft deceleration is not linear, because the deceleration rate of the inside wheel cannot be less than 0, but the net result is that turning stops quickly while fore/aft motion decays in a nicely controllable fashion.

Although I have been able to get this desirable behavior by scripting biased, variable, acceleration and deceleration rates (some apparent bugs in _ACEL, _DECEL, _MAC and _MDEC will be covered in another post), I think that this is really something that should be "built in" to Roboteq's mixing algorithms.

Lenny Robbins (Siena, Italy)
##### Attachments:

6 years 2 months ago #29532659
How was this problem resolved ? I am making a two person wheelchair with a analog joystick controlling a HDC2450. Is it still an issue if so how to resolve it?
Thanks

6 years 2 months ago #29532660 by LROBBINS
It has indeed been resolved. If you send me an e-mail address, I will send you a sample script for strictly analog input, and links to files for a multi-node CANbus system that incorporates a nearly identical script for the Roboteq component. It took a long time to find a solution that works for all possible maneuvers, but it is, in the end, excruciatingly simple.
The following user(s) said Thank You: blake

6 years 2 months ago #29532661
Thanks, This email address is being protected from spambots. You need JavaScript enabled to view it. looking forward to testing .

6 years 1 month ago #29532698
Thank you

6 years 1 month ago #29532699 by LROBBINS
Caro GIordano,

I would very much appreciate any corrections or improvements that you can offer.

Ciao,
Lenny

5 years 9 months ago #29532965 by Rorence

5 years 9 months ago #29532968 by LROBBINS
You're welcome.

5 years 7 months ago #29533088 by Erik
Why not post the script here on the forum so we all can use it if we like?

I also reported this while testing my controller, the steering is not perfect and for a bigger vehicle than mine i guess it can be even unconfortable to steer.

Thanks for this post and i hope the steering will get improved in the firmware.

5 years 7 months ago #29533096 by LROBBINS
The last release of the complete hardware and software for my CANbus wheelchair control system can be downloaded at drive.google.com/open?id=0B3svXvyPGRgral9FU2lJZlpHdFU It is already out-of-date, however, and I will be posting an updated version within the next couple weeks. At the same time, or soon after, I will include an updated direct analog input version of the script in that folder.

I am not posting this here because I want to stop posting multiple versions at multiple sites, so will in the future just use Google Drive as the repository.

However, here's a snippet with the subroutine that corrects the lack of acceleration mixing:
```TurnMix:
DIM TurnCycles AS Integer
TurnCycles = TurnCycles + 1
currentTurnRate = (M1Power-M2Power)/2
IF abs(Steering-currentTurnRate) > 5 'turn changing
currentSpeed = (M1Power+M2Power)/2
'Apply boosted Accel and Decel to Throttle axis less often than to Steering axis
IF abs(Throttle-currentSpeed) > 20 'speed changing during changing turn
IF (TurnCycles MOD (TurnBoost+1)) <> 0 THEN
Throttle = currentSpeed
END IF
ELSE
TurnCycles = 0
END IF 'end of "speed changing during turn"
'increase acceleration and deceleration by TurnBoost if turn changing
M1Accel = M1Accel*TurnBoost
M2Accel = M2Accel*TurnBoost
M1Decel = M1Decel*TurnBoost
M2Decel = M2Decel*TurnBoost
END IF 'end of "turn changing"
RETURN 'END of TurnMix:```
Throttle and Steering are input values (either via CAN or from analog input), M1Power and M2Power are found in the calling routine as GetValue (_MOTPWR, 1) and GetValue (_MOTPWR, 2), and the modified accel and decel values are sent to the controller with
```  SetCommand (_DECEL,1,M1Decel)
SetCommand (_DECEL,2,M2Decel)
SetCommand (_ACCEL,1,M1Accel)
SetCommand (_ACCEL,2,M2Accel)```
when TurnMix returns.

I too would much prefer if this were done in the firmware - particularly in the CANbus system the demands on information transfer to and from the script are at the limit of what the controller can handle, and the less that has to be done in the script the better.

Ciao,
Lenny
The following user(s) said Thank You: Erik