Data Consistency between PM3 & SDK

Post questions and issues with Concept2 PM3 SDK
Post Reply
User avatar
Chris Brett
500m Poster
Posts: 61
Joined: May 25th, 2006, 10:07 am

Data Consistency between PM3 & SDK

Post by Chris Brett » July 17th, 2006, 8:35 pm

I have a few queries regarding trying to match the PM3 data values retrieved from SDK function calls with actual PM3 Monitor values.

1. Data Consistency of SDK Time & Distance Values with PM3 Display.

I have a requirement to replicate the values for distance & time that are displayed on the monitor exactly. I wish to know what the recommended method is.

1a) Should I use the accurate values for time and distance obtained via the CSAFE_SETUSERCFG1_CMD or should I use the standard CSAFE time and distance calls CSAFE_GETTWORK_CMD and CSAFE_GETHORIZONTAL_CMD.

1b) If it is recommended to use the accurate CSAFE_SETUSERCFG1_CMD time and distance calls what method of rounding should be used to convert the fractional values to the integer values displayed on the Monitor? (My guess is that it is to round down to the nearest integer.)

I am sorry if this seems pretty straightforward but I want to check that my values are calculated exactly the same way that the PM3 values are.
I have added a bit more detail below for clarity and in case it may be of interest to anyone.

Data Consistency of SDK Time & Distance Values with PM3 Display.

There are two methods that I can think of for achieving this.

i) Firstly using the accurate values for time & distance that are obtained via the use of the CSAFE_SETUSERCFG1_CMD (Command Identifier 0x1A).

These are CSAFE_PM_GET_WORKTIME (Command Identifier 0xA0)
and
CSAFE_PM_GET_WORKDISTANCE (Command Identifier 0xA3)

A call to both of these functions using the SDK CSAFE_command function tkcmdsetCSAFE_command(unit_address,cmd_size,cmd_data(0),rsp_size,rsp_data(0))
can be made with cmd_data = [1A, 02, A0, A3]

The only potential issue with this is the rounding up or down of the values to match the integer representation on the monitor. Obviously this depends on whether the workout is set to a fixed distance, fixed time or Just Row.

My question is whether the correct rounding function used by the PM3 is

a) to round down to the nearest completed second or metre
i.e.
counting up from 0 seconds 1.51 seconds = 1 second on the PM3 display.
or the counting down equivalent
counting down from 20 seconds 18.49 seconds = 19 seconds on the PM3 display.

or
b) to round up or down depending on whether or not the fractional value of metres or seconds is > or < *.5 metres or seconds.
i.e.
counting up from 0 seconds 1.51 seconds = 2 seconds on the PM3 display.
or the counting down equivalent
counting down from 20 seconds 18.49 seconds = 18 seconds on the PM3 display.

ii) The second option is to use the CSAFE standard time and distance calls.
The Distance value obtained using the following SDK function call.
CSAFE_GETHORIZONTAL_CMD (Command Identifier 0xA1).
The Time value is obtained using the following SDK function call.
CSAFE_GETTWORK_CMD (Command Identifier 0xA0)

A call to both of these functions using the SDK CSAFE_command function tkcmdsetCSAFE_command(unit_address,cmd_size,cmd_data(0),rsp_size,rsp_data(0))
can be made with cmd_data = [A1, A0]

The only problem using these values is that they are given as elapsed values and not as Monitor values i.e.They are always counting up and never counting down as in the case of PM3 Monitor values counting down from a set fixed distance or time.

Obviously this can be resolved by querying the initial values returned from CSAFE_PM_GET_WORKTIME and CSAFE_PM_GET_WORKDISTANCE and if necessary the workout type.

2. Data Consistency of SDK Pace & Average Pace Values with PM3 Display.

I have already had some help on this from Monsieur Lyons but I thought it might be useful to also add some information regarding consistency with Pace values because I haven't quite got them sorted out yet and it may be of use to someone else anyway.

I have had some discrepancies with both the Split time / 500m and calculation of the Average Split time / 500m.

2a) The Split time / 1000m value is obtained using the following SDK function call.
CSAFE_GETPACE_CMD (Command Identifier 0xA6)
within
tkcmdsetCSAFE_command(unit_address,cmd_size,cmd_data(0),rsp_size,rsp_data(0))

I am currently simply dividing the processed response data bytes by 2 as follows. All variables in the following code are declared as Doubles

Code: Select all

pace_Read = (rsp_data(16) + (rsp_data(17) * 256))   ‘pace in seconds / 1000 metres
pace_Tsecs = pace_Read / 2   ‘pace in total seconds / 500 metres
if pace_Tsecs > int(pace_Tsecs) then
	pace_Tsecs =  pace_Tsecs + 1 'rounded up pace in total secs / 500m
end if

pace_Mins = pace_Tsecs \ 60  
pace_Secs = pace_Tsecs – (pace_Mins * 60)

The data values I get are broadly consistent with the values on the PM3 display however I frequently get round off problems where the SDK values vary up or down by 1 second / 500m. I believe that the PM3 is rounding these values up to the nearest 1.0 second, however I still seem to get some discrepencies when using this assumption.

Is this the correct method or am I missing something?

2b) I find it very difficult to get consistent values for the Average Split time / 500m. I calculate this based on the accurate values for time & distance that are obtained via the use of the CSAFE_SETUSERCFG1_CMD (Command Identifier 0x1A).

accurate time is obtained from CSAFE_PM_GET_WORKTIME and accurate distance is obtained from CSAFE_PM_GET_WORKDISTANCE.

Using these values the average pace in seconds per 500 metres is calculated via
Average pace (secs / 500) = accurate Time * (500 / accurate Distance).

I believe that the PM3 is rounding these values up to the nearest 0.1 second so I use

Code: Select all

Average pace = Average pace * 10
if Average pace > int(Average pace) then
	Average pace =  Average pace + 1 'rounded up pace in secs / 500m
end if
Average pace = int(Average pace)
Average pace = Average pace / 10
Obviously the values produced by this method are totally dependent on the sampling time. I am currently sampling the average at the finish of each stroke i.e. stroke state changes from 2 to 3 or 4. The PM3 seems to update the Average pace once per stroke when the pace is updated. This occurs after the end of the drive phase.

Is there a more accurate method of synchronising my calls with the sampling time used by the PM3 to obtain consistent values for the Average Split time / 500m?

Thankyou for your time.

Chris.

haboustak
500m Poster
Posts: 77
Joined: March 17th, 2006, 3:02 pm
Location: Cincinnati

Post by haboustak » July 17th, 2006, 9:52 pm

Is there a more accurate method of synchronising my calls with the sampling time used by the PM3 to obtain consistent values for the Average Split time / 500m?
I look forward to seeing if there's a good answer to that question.


In the meantime... Does the VB function Int() truncate the floating point result to an integer? Where a value of 3.8 would become 3.0?

If so, have you tried a more traditional method of rounding (less than .5 down, equal or more than .5 up) and comparing your results to the value reported by the monitor?

Code: Select all

AveragePace = Int(AveragePace + 0.5)
When C2 rounds, I'd be surprised if they were always rounding up.
Mike

User avatar
Chris Brett
500m Poster
Posts: 61
Joined: May 25th, 2006, 10:07 am

Post by Chris Brett » July 18th, 2006, 6:10 am

Thanks for getting back Mike.

I think that the PM3 always rounds down i.e. 6.9 metres = 6 and the display doesn't increment the distance until 7 whole metres have been completed.(and likewise with seconds)

VB seems to do the correct mathematical round up and down around 0.5 when setting an integer = to a real value.

i.e.

Code: Select all

intMetres = lngMetres
It even does the correct adjustment for a value exactly on the *.5 boundary rounding up and down to an even number.

i.e. 1.5 rounds to 2 but 4.5 rounds to 4

I based the rounding up of pace values to the nearest 1.0 metre on some discussions with C2 in the long and distant past.

Do you always get pace values consistent with the PM3 display? If so what do you do with the raw seconds per 1000 metre integer value?

Any help is greatly appreciated.

Cheers Chris

haboustak
500m Poster
Posts: 77
Joined: March 17th, 2006, 3:02 pm
Location: Cincinnati

Post by haboustak » July 18th, 2006, 1:33 pm

Chris,

I think my eyes might be permanently crossed trying to watch two displays at the same time.

It took me a while to get a full floating-point version for GET_WORKTIME and GET_WORKDISTANCE. I'm confident you've had this part figured out for a while now.

Code: Select all

      for (index=0; index<4; index++) {
         i_time = i_time | (rsp_data[8+index] << (8*index));
      }
	  *time += (i_time  + rsp_data[12]) / 100.0f;

Code: Select all

      for (index=0; index<4; index++) {
         i_distance = i_distance | (rsp_data[8+index] << (8*index));
      }
	  *distance = (i_distance+ rsp_data[12]) / 10.0f;
If I use your method of calculating average pace.

Code: Select all

   float pace = time * (500.0f / distance);
My value of pace varies significantly initially, then as distance and time increases it seems to converge on the value displayed on the monitor. I'm using a JustRow (time and distance counting up) and the monitor is getting extremely consistent values for Pace (so my strokes are nearly equal power over time). In my calculations, I'm maintaining all available precision until the very end (no rounding on Time or Distance). I'm confident after experimentation that this is not a sufficient method for matching the monitor regardless of rounding.

If I use the CSAFE_GETPOWER_CMD I can get a value for power that matches the display, and using that I can calculate an instantaneous pace. This seems to match the (non-average) pace value on the monitor using a standard round about 0.5f.
float pace2 = roundf(500.0f/powf((power/2.8f), 0.333333f));

I'm pretty confident that the monitor calculates average Power and it uses that value to calculate average Pace.

Trying to calculate average Power might suck. I don't think sum(Power per Stroke) / count(strokes) would work. Power is already an average (energy per unit time), so to average an average you have to take into account the time per stroke (which would properly weight the averaged power values).

It might be something like: Sum(Power per Stroke * Time per Stroke)/(total time). This would give you dE / dt, which should once again be Power.

Compare the value the monitor displays for Ave Watt to the value it displays for Ave Pace based on the relationship:

Code: Select all

P = 2.8v^3
I thought I was pretty good in Physics in college, but I don't seem to be good enough. I've been considering visiting the physics department of the local University with a 12-pack and see if I can't muster up some help working with Torque and Power properly.
Mike

User avatar
Chris Brett
500m Poster
Posts: 61
Joined: May 25th, 2006, 10:07 am

Post by Chris Brett » July 19th, 2006, 3:50 am

Thanks again for the help Mike. I found very similar results RE: steady convergence of average split but never managing to get the values to correspond exactly.

I will have a play with your Power suggestion and get back to you. I am busy for a couple of days though.

Do you recommend using power for pace as opposed to average pace and have you managed to replicate the PM3 pace value exactly? I always seem to get the occasional value 1 out from the PM3.

Thanks again Chris

Post Reply