Using RunningDynamicsData.groundContactBalance and other metrics in a datafield

I tried incorporating the running dynamics data. It didn't work in the Garmin simulator, but I wasn't sure whether that data is simulated by the simulator. However with a HRM-run connected to my Fenix 5s plus watch it didn't work either. So the code isn't correct, although I get no errors in the simulator or on my watch.

I have used:

using Toybox.AntPlus as Ant;

.......

fieldValue[i] = (Ant.RunningDynamicsData.groundContactBalance != null) ? Ant.RunningDynamicsData.groundContactBalance : 0;

Can someone shine a light on this?

  • Since this is DF, have you tried it along side the native GCT DF on device?  That way you see see what to expect.  I know in using the native fields for this, you often won't see data if you're just walking.

  • Good suggestion! I was walking the dog while testing this, with only a very short running.

  • I doubt you'd see much with that.

  • When running the values stay at zero also. When I do a System.println(Ant.RunningDynamicsData.groundContactBalance) in the simulator an array is returned with 11 values of current metrics like cadence, heartrate and alititude.

    I tried this code that is on https://forums.garmin.com/developer/connect-iq/f/discussion/223986/what-is-the-difference-in-accuracy-speed-of-update-getrunningdynamics-vs-runningdynamicslistener by Travis:

    // Separate class...
    class RunDynamicsListen extends Toybox.AntPlus.RunningDynamicsListener {
    	var dynamics;
    	
    	function initialize() {
    		RunningDynamicsListener.initialize();
    	}
    	
    	function onRunningDynamicsUpdate(data) {
    		dynamics = data;	
    	}
    }
    
    // In DataField
    hidden var listen;
    hidden var dynamics;
    
    // In DataField.initialize
    if(Toybox.AntPlus has :RunningDynamics) {
    	listen = new RunDynamicsListen();
        dynamics = new Toybox.AntPlus.RunningDynamics(listen);
    }
    
    // In compute
    if(listen != null) {
        var o = listen.dynamics;
        // Etc.
    }

    In the simulator System.println(o) delivers a null value, when it is simulating data. Do I need to call anything else to get values?

  • I am still strugling with this. I tried the simple example that Travis did in the same thread (Link to thread):

    // In DataField
    hidden var dynamics;
    
    // In DataField.initialize
    if(Toybox.AntPlus has :RunningDynamics) {
        dynamics = new Toybox.AntPlus.RunningDynamics(null);
    }
    
    // In DataField.compute
    if(dynamics != null) {
        // Etc.
    }

    System.println(dynamics) gives Obj: 230 every second.

    How do I get the running dynamics inside this object?

  • See "RunningDynamicsData" in the API doc.

  • The object referred to by the name dynamics is a RunningDynamics object. The methods you can call are listed in the documentation for that class. From the documentation, you can see that it has a getRunningDynamics() method which returns a RunningDynamicsData object, and that has fields that you are interested in like cadence, groundContactBalance, ...

    So the code would look something like this...

    if (dynamics != null) {
    
        data = dynamics.getRunningDynamics(); // gets a RunningDynamicsData despite the name
        
        // the data you want
        var cadence = data.cadence;
        var groundContactBalence = data.groundContactBalance;
        var groundContactTime = data.groundContactTime;
    }

    Please take a look at the documentation and try to understand what this code is doing. I'm providing references to the documentation and snippets of code to try to help you to learn how figure this stuff out on your own in the future.

  • I appriciate your feedback Travis. I have been abIe to make some datafields that made users of the Stryd footpod very happy, and in general didn't have to ask for help, but sensor-related stuff is hard to comprehend. Sorry for that.

    I expected something like your last snippet to work and did try that, but I kept getting errors. Even with your snippets together in a simple datafield, with the following code, I have a crash in row 28 with the error: "Error: Unexpected Type Error         Details: Failed invoking <symbol>" with the stack error being 0x100000c9:

    class SteplengthtestApp extends Toybox.Application.AppBase {
    
        function initialize() {
            AppBase.initialize();
        }
    
        function getInitialView() {
            return [ new RunningDynamicsView() ];
        }
    }
    
    
    class RunningDynamicsView extends Toybox.WatchUi.DataField {
    	hidden var dynamics;
    
        function initialize() {
            DataField.initialize();
    		if(Toybox.AntPlus has :RunningDynamics) {
        		dynamics = new Toybox.AntPlus.RunningDynamics(null);
    		}
        }
    
    
    	function compute(info) {
    		if (dynamics != null) {
     		    var data = dynamics.getRunningDynamics(); // gets a RunningDynamicsData despite the name
    		    // the data you want
        		var groundContactBalance = data.groundContactBalance;
        		var groundContactTime = data.groundContactTime;
        		System.println(groundContactBalance);
    			System.println(groundContactTime);     		
        	}
        }
    }
    I expect to get a value like 49.03125 for data.groundContactBalance on row 28. When I comment rows 28 to 31 out and do a System.println(data), it shows a "null" value in the simulator. The simulator is set to simulate data, so I would expect data to have values.

    Is it the simulator not simulating running dynamics data? That would also explain why I kept getting errors earlier on this last month while trying to get code working.

  • I expected something like your last snippet to work and did try that, but I kept getting errors.

    Yeah, I made the cardinal sin of not checking for a null...

    if (dynamics != null) {
    
        var data = dynamics.getRunningDynamics(); // gets a RunningDynamicsData despite the name
        if (data != null) {
    
            // the data you want
            var cadence = data.cadence;
            var groundContactBalence = data.groundContactBalance;
            var groundContactTime = data.groundContactTime;
        }
    }

    That should not crash and if the data is available it should be fine.

    Is it the simulator not simulating running dynamics data? That would also explain why I kept getting errors earlier on this last month while trying to get code working.

    Yes, the simulator does not simulate any ANT+ data. I'm pretty sure you have to test this stuff on device.

  • Indeed this works with my HRM-run. Thanks