Changes

→‎Network protocols: Start documenting some telemetry protocols
Line 374: Line 374:  
=== Teleoperation ===
 
=== Teleoperation ===
   −
The kart is operated over UDP port 5102. This port is only open when the kart is in [[#Command 0x04: SetState|drive state]] It expects packets of the form:
+
The kart is operated over UDP port 5102. This port is only open when the kart is in [[#Command 0x04: SetState|drive state]]. It expects packets of the form:
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 414: Line 414:     
'''NOTICE:''' ''Home Circuit'' contains logic to detect when the kart is being held, and it locks out the controls in such cases. This logic is not implemented in the kart, which will eagerly follow any valid throttle/steering command given. The kart is not likely to cause injury if operated while held, but nevertheless, if you do so, it is at your own risk.
 
'''NOTICE:''' ''Home Circuit'' contains logic to detect when the kart is being held, and it locks out the controls in such cases. This logic is not implemented in the kart, which will eagerly follow any valid throttle/steering command given. The kart is not likely to cause injury if operated while held, but nevertheless, if you do so, it is at your own risk.
 +
 +
=== Telemetry ===
 +
 +
The kart will send UDP packets to the Switch over a port it specifies in "connection_info" (but typically port 5116) indicating its current status. The packet type is indicated by the first byte. (The tables below ignore this first byte.)
 +
 +
==== Type 0x01: Battery Status ====
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x3
 +
| Zero padding
 +
|-
 +
| 0x3
 +
| 0x1
 +
| How many bars to show in the HUD for battery status (0x00-0x04)
 +
|-
 +
| 0x4
 +
| 0x1C
 +
| Zero padding, to bring total packet length to 0x20.
 +
|}
 +
 +
One would think this would be a good location for wireless metrics (e.g. RSSI), but this is presumably measured only on the Switch side of the link.
 +
 +
==== Type 0x02: IMU ====
 +
 +
The kart contains a 6DoF IMU for measuring movement. This packet type communicates the motion status.
 +
 +
All integers are little-endian:
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
!colspan="2"| Description
 +
|-
 +
| 0x0
 +
| 0x2
 +
|colspan="2"| Total IMU samples, as an unsigned integer. This number includes the samples in this packet. It overflows.
 +
|-
 +
| 0x2
 +
| 0x1
 +
|colspan="2"| Flags bitfield: PCCCCNNN. P=High-precision, C=Unknown, possibly clipping indicators. N=Number of IMU samples.
 +
|-
 +
| 0x3
 +
| 0x1
 +
|colspan="2"| Pad byte; zero.
 +
|-
 +
| 0x4
 +
| 0x4
 +
|colspan="2"| Microsecond-precision timer, as an unsigned integer.
 +
|-
 +
| 0x8
 +
| 0x10
 +
|colspan="2"| Orientation: s32 qi, qj, qk, qr; gives the coefficients of a quaternion. Units appear to be increments of 2^-30, but quaternions should always be normalized before use.
 +
|-
 +
| 0x18
 +
| 0xC
 +
| Integrator A position
 +
|rowspan="2"| s32 x, y, z; gives an estimate of total displacement since this integrator was reset. Units: unknown
 +
|-
 +
| 0x24
 +
| 0xC
 +
| Integrator B position
 +
|-
 +
| 0x30
 +
| 0xC
 +
| Integrator A velocity
 +
|rowspan="2"| s32 x, y, z; gives an estimate of total change in velocity since this integrator was reset. Units: ~2^-19 m/s
 +
|-
 +
| 0x3C
 +
| 0xC
 +
| Integrator B velocity
 +
|-
 +
|rowspan="2"| 0x48
 +
|rowspan="2"| 0xC*(NNN+1)
 +
|rowspan="2"| 1-8 raw IMU samples
 +
| s16 accel_x, accel_y, accel_z; // in units of 0.000244 Gs. 1G is added to accel_z to compensate for gravity.
 +
|-
 +
| s16 ang_vel_x, ang_vel_y, ang_vel_z; // in units of 0.004375 degrees per second.
 +
|}
 +
 +
The exact rate at which these packets are sent appears to be somewhat variable. The raw IMU samples seem to be collected with a period of 6ms, and when not in drive mode, this packet always contains 8 IMU samples, for an overall period 48ms. However, when in drive mode, not all of these packets contain exactly 8 IMU samples, and the packets will arrive at an uneven rate. This is probably due to some logic in the kart that flushes the buffer early based on certain conditions.
 +
 +
The IMU itself is mounted on the PCB "upside down" which gives a reference frame different from what one would expect: While +X does correspond to the driver's right-hand side, the +Y vector extends beyond the rear of the vehicle, and +Z extends out the bottom. All measurements are taken with respect to this reference frame.
 +
 +
The orientation quaternion is reasonably stable, but should still only be trusted for relative measurements over short periods of time, as the quaternion can drift due to error (noise, clipping, quantization) in the IMU samples. The quaternion is initialized to 1+0i+0j+0k once the IMU is enabled (i.e. when "connection_info" is set).
 +
 +
The integrators are useful in an environment where packet loss is expected to be reasonably high, and so not all raw IMU samples can be reliably collected. The integrators are periodically reset (every 0x2000 samples), as they will accumulate error over time.
 +
 +
Both integrators are reset at the same time when the IMU is enabled, but integrator A is reset at sample 0x1000 so that the resets are staggered.
 +
 +
If the 'P' bit is set, the integrator values are multiplied by 78.5(???) prior to being sent, for added precision. The kart will always set the 'P' bit as long as all integrator values are small enough to permit it.
 +
 +
==== Type 0x03: Motion feedback ====
 +
 +
TBD
    
= Versions =
 
= Versions =
30

edits