Rover S-Curves alpha testing

Hi @McKey,

I’m happy to provide pre-built binaries for any boards people want to test with. In the top discussion above I’ve placed a link to a Pixhawk1 binary. Thanks for giving it a try!

Keen to try this - will probably only be able to give it a go in simulation at the moment.

I have a question: will the vehicle follow the same path regardless of speed (up to some sort of g limit)?

Are you basing the path on geometry or turn rate / lateral acceleration?

I think it is important to be able to make the vehicle follow the same path at all speeds. Does the vehicle follow a circular path through the corner (thus it would be possible to have a constant turn radius, and vary the turn-in point depending on the angle between the current and next waypoint?

One thing I’ve noticed with L1 is that it tends to turn in hard, then can take a while to track to the path, rather than setting itself up on a steady curve to intercept the new path.

I built the SITL target today and unfortunately got called away from the desk just as I was connecting the test case in MP.

I intend to live test tomorrow on the mower with a Cube Orange.

1 Like

Hi @mroberts,

I think speed will have less of an effect on the path but will still have some effect. For example at lower speeds the SCurves will plan the turn so it passes very close to the waypoint. At higher speed it will turn earlier but the vehicle’s maximum distance from the waypoint will never be more than WP_RADIUS so the vehicle may slow down if necessary to keep the lateral acceleration low.

I have also seen that L1 responds very differently at low speeds compared to high speeds and I think this is improved with this PR because it also replaces the L1 controller with a Position Controller that is similar to what we use in Copter. I suspect that if there are performance problems it will be in this area rather than in the SCurve path planning.

Hi @rmackay9 I really like the consistent turn radius.

I can see that it slows down if the corner is too tight, but I don’t yet understand how to tweak that - I think it would be good to understand when / why it decides to slow, because it looks like it’s being quite conservative on the speed.

Here’s a sample mission in sim. You can see at WP 3 the effect of increasing WP RADIUS. It’s going into that corner at 5m/s and slows to 2m/s through it. Also of note is how the radius changes, and it takes a while to get back on track afterwards, compared to WP 2.

However, it also slows to 2m/s for WPs 4-8 - a far gentler corner.

I like the uniform turning radius through WP2, but I think the slow down is excessive from 4-8.

From a mission planning perspective, I’d like to be able to define a nominal turn radius and a maximum g, and have the vehicle follow that radius at all speeds, until it hits turn_max_g, then slow to maintain the g.

For ground rovers in particular, confidence, repeatability and predictability I think are much more important than in air vehicles - mowers need to ensure coverage, and road-based vehicles need to stay on the road.



I don’t have a full answer immediately but one oddity of SCurves is that they will slow down if waypoints are placed too close together. There’s a built in assumption that the vehicle must be able to stop by the time it reaches the “next next” waypoint.

BTW, sometimes people add lots of waypoints in order to draw a curve. We could potentially add spline waypoint support to provide another way to produce a curve with fewer waypoints.

For boats that I care about I guess the most critical ability is precision in passing through or arriving at points. For pure bathymetric mapping then the thoughts shared for rovers above are valid. Not very important driving through open waters, but boats will also travel along water edges or islands where path precision is really important (we likely need to undress and swim to save a boat caught in an obstacle).
But in general, getting as close as possible to a point is paramount. The boats in mind (fisherman’s bait boat that drops tackle at and/or feeds the fish at a particular underwater feature) typically travel slow. Like 1-2 m/s usually at the lower end. I understand the comments that the slow speed will underhelp getting close. As will a narrow WP radius. That reminds me of other discussions in these forums where the advice was to avoid setting the radius too short as it could impact cornering significantly. Ideally, our boats should aim for a wp radius of no more than 0.5 meters (depending on GPS precision, probably). Are the current concerns of a short wp radius still valid for S-curve, or does S-curve instead open an opinion to shorten it?
These boats, at least the models using skid steering, are usually highly capable of doing pivot turns on the spot as well. Ie cornering at the point seems like a more appropriate ability than a consistent turn radius (might not need to be a contradiction).

Spline support would be awesome. I often mow around curved landscaping edges, and my waypoint paths are sort of clunky to avoid hitting anything. Spline waypoints would likely help a lot there.

Downloaded and installed the CubeOrange binary above, and it hangs at boot time. The speaker plays its usual happy tones, then one long, high pitched beep, then reboots and does the same…endlessly.

I found the issue. SERVOx_FUNCTION=-1 does not work to define GPIO pins for this branch. Instead,
SERVO_GPIO_MASK defines those. Ok, now maybe I can drive…

Initial impressions are positive. As far as the planned vs actual path, it’s about on par with previous L1 performance, if slightly better after a little PSC_VEL* tuning. Pivot turn behavior is decidedly worse. It sort of ratchets through the turns in 2-3 increments, and often overshoots, causing an oscillation leaving the turn. ATC_STR_ANG_P changes do not seem to affect that behavior. It’s also pausing at nearly every waypoint, which is something it tended to do before but now seems exaggerated.

I have a persistent unhealthy AHRS warning that was not previously present, and I can’t figure out why just yet. A look at the logs may reveal that.

Overall, it’s perfectly usable, and I think we are headed for a huge improvement. The position controller will likely prove easier to tune than the L1 controller, and turn performance will almost certainly improve over previous.

I will get some video footage and retrieve a log file or two later today.

Please let me know if there are specific test cases you’d like to see. The waypoints above are representative of the kind of geometry I tend to mow, so that’s what I used.

Unrelated to S-Curve, but perhaps a newly minted “feature” of 4.2 - I have MIS_OPTIONS=0, but every time I reboot, the waypoint mission that I had loaded seems to disappear. It’s become quite frustrating! (I do run a script that’s capable of clearing missions, but I think I’ve ruled that out as causal)

Some video footage from today’s testing. A review of the log shows some pretty high yaw innovation values, possibly accounting for the yaw offset seen in the log viewer footage. I may need to recalibrate everything after all the firmware changes today.


Some follow ups as I get ready to do a little more S-Curve exploration today:

I cleared the AHRS fault with a full 3-axis re-calibration, which hopefully improves the yaw innovation values as well.

I conclusively proved that scripting is not the cause of the waypoints disappearing between boot cycles. Something in this branch deletes all waypoints upon reboot regardless of MIS_OPTIONS value.

With no changes other than disabling steering acceleration limiting (ATC_STR_ACCEL_MAX=0 from a value of 100 deg/s/s/), I went from Mr. Toad’s Wild Ride at this sharp pivot, to a very controlled slight overshoot of the heading. The mid-turn pauses are still present.

image image

Disabling acceleration limiting (ATC_ACCEL_MAX=0), however, resulted in Internal Errors 20000000.

Increasing ATC_STR_ANG_P to a ridiculously large value of 5 (from 1.7) along with increasing ATC_TURN_MAX_G to an impossible to achieve value of 5 (effectively taking it out of the loop) seemed to improve performance a bit, with less (but still some) stutter-stepping in the turns. I want to keep exploring the relationship between those values when I can. The last path that the mower tracked before a servo malfunction was very nice!

Pivots seem to a be less “pure” than with the L1 controller. The outside wheel turns faster than the inside wheel, resulting in a positive turn radius (as witnessed in the last pic I posted of the zoomed in sharp turn).

Here’s the best I achieved:

But…I burned out a drive servo, so that’s all I can do today. I won’t blame the new firmware for it - that servo has seen plenty of use and abuse over the past year. Replacements should arrive early next week.


Hi @Yuri_Rage,

Thanks very much for the testing and feedback including the video.

I guess maybe the issue with the pivot turns is that it is not actually using the pivot turn controller but is instead falling back to the position controller. Maybe when your servo is replaced you could try adding a delay to the waypoint commands? The “delay” is the first field in the command.

Some warnings and known issues
Skid-steering vehicles will not pivot at a corner unless the waypoint command’s “delay” field (the first field) is set to 1 (or higher). I suspect I should change this behaviour so it is like master and pivots at any corner where the angle is at least WP_PIVOT_ANGLE.

I thought this might be confusing/annoying to have to add the “delay” but I also thought it might be interesting to see how the position controller did without the use of the pivot controller. I think we can safely assume the answer is, “not well” so I’ll modify the branch so that it always checks the angle of the next corner and uses the pivot controller if it is > WP_PIVOT_ANGLE.

Re the other two issues with SERVO_GPIO_MASK and disappearing missions, I’ll have a play and see if i can reproduce these. I suspect the SERVO_GPIO_MASK issue has been fixed in master and I’ll just need to rebase this PR.

Thanks again.

1 Like

Thanks for the reply, Randy! I did have WP_PIVOT_DELAY=1, but I did not have each waypoint delay set as you suggest. Will do that next!

I’d also suggest that “not well” is more like “not bad,” but not quite up to expectation :slight_smile:

I feel like I was really making progress before the servo fried. The tuning is quite different from previous, and I was just starting to figure it out when disaster struck. I REALLY like the oscillation recovery after the pivot that induced it, and I think a better tune will leverage the new controller well!

And a late edit - I wanted to send you a .bin log for the better tuned results, but my session was cut short. The only log I have is probably several hours of power-on time, long periods of inactivity, multiple restarts, and a few promising results sprinkled in. I’ll get some good data soon!

1 Like

This is awesome to see. Everything I see above looks great except I was concerned about the pivot turns, since that is something that is working super well, in my opinion, with the current pivot controller. SCurves with the old pivot controller is looking promising. I will try to get my vehicle out and give this a try as well, but I can’t expect that I will add anything to Yuri’s analysis since our vehicles are so similar. But I would like to join in the fun!


I’ve updated the binaries linked in the description at the top to a new 21-Dec-2021 version of the SCurves feature. The changes vs the 14-Dec-2021 version are:

  • Vehicle always pivots at corners with angle > WP_PIVOT_ANGLE (no need to set each waypoint’s “delay” field)
  • Rebased on master (should fix the SERVOx_FUNCTION=-1 hang issue)
1 Like

What is the preferred/intended method to define GPIO pins? Should I be using the SERVO_GPIO_MASK or individual SERVOx_FUNCTION params?

On one hand, the bitmask is convenient, but on the other, the servo function params are a bit easier to read and maintain. Is there a plan to deprecate one of them?


After a quick discussion with @tridge we think setting the SERVOx_FUNCTION parameter is the easiest and most intuitive way to set the pin to be a GPIO. The SERVO_GPIO_MASK will also work just as well but we think this is more for those unusual cases where the user has the servo on CAN or SBUS and then also wants to use the physical Servo pin on the autopilot as a GPIO.

1 Like


Another thing that occurred to me as I walked the dog was that I set the default PSC_VEL_D term quite high (0.3). Now I see you’ve reduced it to 0.1 which is a good thing because a high D term can easily lead to overly active servo outputs which could lead to servo burn-out like you experienced. Hopefully this was not the cause of your vehicle’s servo’s burn out but it’s something testers should be craeful of.

… so to put it more simply an concretely, maybe I should reduce the default PSC_VEL_D value from 0.3 to 0.2 and/or testers should reduce this value themselves on the first test.

Agreed about PSC_VEL_D! I think it’s also prudent to watch for I term windup, though I can’t say for sure that I experienced any of that.

My methodology for manually tuning almost always includes initially zeroing the I and D terms (along with P if FF is to be used). My goal is to minimize the use of any term other than FF (or P). I wondered what drove you to use such a high D term value.

I’m also hoping to drive ATC_STR_ANG_P down from the huge value I tried last. I expect your most recent pivot controller change will allow for that.

Again, I’m not blaming the new firmware for the servo issue, though it’s within the realm of possibility. I was being lazy/foolish with my testing methodology and not watching as closely as I should have (staying warm!), and I’m sure I’ve abused that servo more than once outside the scope of this testing, anyway.

I suspect that servo was slowly moving toward failure during the latter part of my test session. I began to fight basic steering tuning in a way I had not expected before finally just spinning in circles when the left side failed entirely.

1 Like


Great. The high PSC_VEL_D term came from testing with my AION robotics rover. I found that without the high D-term it was wavering a lot even on straight sections of the path. I must say I was in a bit of a rush though so perhaps with more effort I could have found another balance of gains that would have worked as well.

1 Like

Hey guys,

I’d be interested in doing some higher speed testing with this controller at some point (60-90mph). Is there any way we could get a list of ‘test cards’ you would like to see dedicated effort on so we can step up to that goal?

I’m curious how this controller with the PSC variables enhance braking in the approach to a WP (vs the L1 controller) with our external throttle / brake / shift mixing logic.

Odd you mention the PSC_VEL_D term - we had the same issues in tradheli before everyone switch to Loiter…

Along the way we may need to help create an enhanced tuning guide with all the different steering methods considered (skid, Ackerman, anti, parallel, etc.).

1 Like

@rmackay9, I got new servos installed, tuned in acro mode, and got things running at least as well as previous (possibly better!). I didn’t do a lot of testing before it got dark, but I did install the 21 Dec binary.

Observations so far:

The waypoint mission still disappears between boot cycles.

There is a pronounced delay at each turn now, even with WP_PIVOT_DELAY=0 and all zeros in the delay parameter column for each waypoint. It’s almost as if the autopilot has to stop and “think” at each waypoint before proceeding.

However, pivots are clean and crisp, and tracking between waypoints is quite straight.

I can send a log your way if you like.

1 Like


Thanks for the offer on testing at high speeds.

I think some important tests could be:

  • does it track along the straight line between waypoints at least as well as 4.1? Repeat this test at various speeds including very slow speeds
  • compare cornering
    • does the vehicle pass no more than WP_RADIUS from the waypoint? Test at various speeds and with various maximum accelerations (ATC_ACCEL_MAX and ATC_TURN_MAX_G)
    • test corners of various angles (e.g. 45deg, 90deg, 180deg)
    • how do you feel about cutting the corner vs overshooting?