roboticslab-uc3m / yarp-devices

A place for YARP devices
https://robots.uc3m.es/yarp-devices/
9 stars 7 forks source link

Encode fractional part in fixed-point target values #210

Closed PeterBowman closed 5 years ago

PeterBowman commented 5 years ago

In several places, a magic 65536 value is introduced:

https://github.com/roboticslab-uc3m/yarp-devices/blob/d747fa641e798d3a606e6aecf25f04bcbdff96d4/libraries/YarpPlugins/TechnosoftIpos/IPositionControl2RawImpl.cpp#L201-L206

This factor is equivalent to a 16 left-shift (bitwise shift, i.e. value << 16), consequently used to fit a float into a 32-bit integer expressed as 16.16 (16-bit integer part + 16-bit fractional part). Currently, we cast this float into an integer, so that the fractional part is elided, and the result is left-shifted so that the left (MSB) 16-bit half is filled up.

Obviously, we are losing precision in that the fractional part would be always null (all 0x00's). Let's change this. For better understanding on how fixed-maths work, see http://www.hugi.scene.org/online/coding/hugi%2015%20-%20cmtadfix.htm and https://planetcalc.com/862/. Also, the iPOS user manual provides an useful example in section 9.4, PVT absolute movement example (in this case, a 256 scale is used).

PeterBowman commented 5 years ago

Occurrences:

Edit: the 65520 factor is used to convert to/from internal units (UI).

unnamed

(where "Ipeak" is the drive peak current expressed in [A], see ESM > Drive Setup > Drive Info)

PeterBowman commented 5 years ago

As suggested by @munozyanez, we need to check whether the "Enable high speed resolution speed estimator" option is checked, within ESM > Driver Setup > Control mode/Advanced. The drives might ignore the fractional part if this is not set.

Captura de pantalla de 2019-05-17 19-41-35

See also section 1.5. CANopen factor group setting regarding factor groups.

(...) access to the scaling factors for position, speed, acceleration and time objects. These settings are linked directly to the objects 6089h, 608Ah, 608Bh, 608Ch, 608Dh, 608Eh, 206Fh,2070h, 6093h, 6094h, 6097h and 2071h. This means that these settings can be chosen either from Setup or by later setting the objects themselves. (...)

(...) the user can set the factor numerator and divisor in order to obtain the needed scaling. The dimension and notation index (and their linked objects) have no influence over any scaling. Their purpose is only to define an [SI] unit name like rpm, rad, deg, etc. The factor group settings are stored in the setup table. By default, the drive uses its internal units. The correspondence between the drive internal units and the [SI] units is presented in the drives user manual.

Remarks:

  • the dimension and notation index objects (6089h, 608Ah, 608Bh, 608Ch, 608Dh, 608Eh, 206Fh and 2070h) have been classified as obsolete by the CiA 402 standard. They are now used only for legacy purposes, on CANopen masters which still need them.
  • because the iPOS drives work with Fixed 32 bit numbers (not floating point), some calculation round off errors might occur when using objects 6093h, 6094h, 6097h and 2071h. If the CANopen master supports handling the scaling calculations on its side, it is recommended to use them instead of using the “Factor” scaling objects.
munozyanez commented 5 years ago

Keep in mind that TechnoSoft support technician said that this option is currently being tested and should be used carefully. Also the iPos firmware should be checked in order to be sure that the option works as it should.

PeterBowman commented 5 years ago

Example: velocity 24-bit value encoded as 16.8 here.

PeterBowman commented 5 years ago

https://github.com/roboticslab-uc3m/yarp-devices/issues/210#issuecomment-493665173

Same config as axis ID 19 (firmware F508F). Axis ID 15 and others (F508D):

drivesetup15

PeterBowman commented 5 years ago

From EasySetup help:

Speed computation – If you application is using a low resolution incremental encoder, check the Enable high resolution speed estimator option to increase the resolution with which the speed is estimated from the position sensor.

PeterBowman commented 5 years ago

Currently, we cast this float into an integer, so that the fractional part is elided, and the result is left-shifted so that the left (MSB) 16-bit half is filled up.

Not quite so. Let's assume we want to encode 9.8 as integer+fractional 16.16 data:

Therefore, 65536 * val yields the same result as splitting val into integer and fractional parts and applying all necessary operations. I was not aware of the fact that decimals are preserved as a result of this int*double operation - note that bitwise operations are not allowed on floating point values.

Long story short, this could have been closed as invalid. However, the fixed-point maths are now clearer. In spite of rendering the same result, a pinch of technical debt has been addressed at https://github.com/roboticslab-uc3m/yarp-devices/commit/19d805c49501d5dabae65737ba34a13da7c31168.

PeterBowman commented 5 years ago

Oh well, some CAN objects do not store integer and fractional parts contiguously, e.g. PVT points (see https://github.com/roboticslab-uc3m/yarp-devices/issues/210#issuecomment-508943539). So, having encode/decode methods is actually beneficial.

PeterBowman commented 4 years ago

Turns out the fractional 16-bit part is ignored in firmware revisions F508J and below, only the integer part was used (at least regarding the "speed reference while in speed mode").