Grade Calc - Community Project

I'm still not happy with CIQ Grade calcs. I live in Florida (mostly flat) so I really don't have a lot of real world opportunities to test Grade. On the other hand, these subtle rollers are some of the most challenging use cases to test the algorithm. The problem seems to be that barometric values aren't updated quickly - and then they tend to jump in a step function when they do change.

Even up steeper grades like Colorado passes that I got to ride last weekend, barometric data isn't smooth. A balance is needed between grade being noisey (due to barometric jumps) or slow to respond (due to smoothing out those jumps). I've tried to make the balance factor adaptive. So it detects a slope inversion or a transition to/from flat roads faster.

Even the native grade values are slow to respond. However, Garmin apparently did a lot of work on this problem in the new Garmin EDGE 1050 (according to DC Rainmaker's beta evals) and now the native grade is dramatically better. As soon as you hit a steep grade from a flat road, for example, grade will reflect a legit value, not slowly adjust over 10-15 seconds. Maybe using the accelerometer sensor to assist?

Anyway, Garmin still refuses to expose native Grade to CIQ. So we have to figure this out on our own.

I am thinking about a Community Effort to optimize the CIQ Grade calcs. I'll create a DF that only generates grade, and that writes to the FIT file, with some User Settings for various variables. I'll display the current grade as well as a line graph of grade to show how our algorithm adapts to slope changes, slope inversion, and transitions to/from flat roads. And I can display this and the EDGE's native grade on the same screen to compare.

I'll post the CIQ Code in GIT Hub and allow contributors to check out, and update. I bet we can come up with a barrel pretty quick that does a great job.

This image shows a pretty steep sustained grade (grey is the elevation profile, blue is my current GRADE calc). Now that I write a FIT graph I have more visibility into the dynamics and I clearly need to smooth it a bit more. I had tried a Kalman Filter at one point that also seemed ok, but not good enough.

If you are interested in joining the project, let me know.

  • Ok I'm back from a vacation and just did some experiments. I wrote the native "Activity.getActivityInfo().altitude" to the FIT file. I converted FIT to CSV and in EXCEL it looked like my custom altitude data was actually about 12 seconds ahead of the native elevation data that is automatically included in the FIT file from the device! Wild. The native elevation data seemed to be exactly tracking with with the 2-stage filtered barometric data. Anyway, this seems to suggest that the ActivityInfo Altitude data is actually a better source for getting faster insight into actual altitude changes than using barometric data, and even better than the native elevation data that the device uses. I'll double check this, but that is what it appears to be.

    Based on that, I'm trying a least squares approach to model the grade, using a scatter plot of distance and altitude. I'm trying several different LS queue depths, from 4 to 14, so see what I like best in terms of speed -vs- noise. I'm guessing I'll find that around 10 matches that Garmin Edge 1030 grade metric... but I'll find out soon. I just got my EDGE 1050, so I'll also compare to what may be a new algorithm.

  • any way to save accelerometer data? is it exposed to CIQ?  Some evidence showing up that they might be using it also in the "new grade" estimations.

  • Yes, you can get the raw accelerometer data. It's a bit tricky to save it to fit though, 'cause you can only save 1 value per second (in theory you can do arrays but I wasn't able to figure it out, if anyone knows, please share, I'd like to use it to save heartbeats (rr-intervals)

  • I lost you somewhere in the middle. What is altitude data and what is elevation data?

  • My interpretation is altitude data is referring to "Activity.getActivityInfo().altitude" and elevation data is what is natively recorded in the FIT file.  I'll let Dave confirm, but I'm curious as to how elevation tracks to "Activity.getActivityInfo().rawAmbientPressure" as this is supposedly unsmoothed and only temperature compensated.  Dave, did you happen to add rawAmbientPressure into the FIT file?  Any chance you could share the spreadsheet?

  • If I understood correctly, you are saying the altitude, calculated by Garmin, and normally saved in all FIT files, is 12s delayed in relation of speed, position, etc in the FIT file due to its extensive filtering?   (they could have shifted it back for best alignment (or delayed everybody else while saving) but decided not to)?

    If that is the case, how does it help you?   Or are you saying the getactinfo.altitude is actually 12s earlier than the saved elevation, so easier for you to use to derive grade without large delays?

    unclear to me.

  • It would be amazing to have a barrel for grade calculations. Seems like grade calculations would be useful in a lot of apps. Garmin shot themselves in the foot when not making the grade available.

  • I'm made some important changes and fixes. Right now I use 10 and 14 sec Least Squares slope analytics using Distance/Altitude. I also show Raw Grade and my old method. I save Old Grade as well as the new 10 and 14 sec Least Squares grades to the FIT file, so I can see the graphs in Garmin Connect post ride. I setup a screen to show the native device grade and my data field in a 2 field screen... so watch the sensitivity of these methods as I ride. I've done some extra things to help eliminate noise on flat roads and the artifacts that seem to cause errors when slowing down. I should get to an approach I'm happy with soon. If you get a chance to try let me know if you like either of the Least Squares version.

    apps.garmin.com/.../f0ddadf0-4eb1-41fc-ae62-3b94575109ab

  • 1. do you think that the optimal numbers you'll come up with will be the optimal for others? Can it depend on which edge they have? Or what terrain they are riding on?

    2. do I understand correctly that using your algorithm with the 10sec setting means that there's (at least *) a 10 second delay? Is this till better than the 1050's new built-in algorithm?

    *) because we don't know if the raw data your algorithm uses has any delays

  • You mentioned you would like to make the code publicly available? That would be great. I would like to convert it so that it also runs on a 530. Just make sure that you specify a license. For example, https://github.com/mizamae/GarminSlopeDatafield seems to be a great project but without a license nobody can reuse their code.