Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Fisch37/96fe7672487ba44d18fd94cfa218d5d5 to your computer and use it in GitHub Desktop.

Select an option

Save Fisch37/96fe7672487ba44d18fd94cfa218d5d5 to your computer and use it in GitHub Desktop.
Anki Overdrive SDK Light Protocol

This gist covers the semantics of the SET_LIGHTS and SET_LIGHT_PATTERN packets specified in the communication protocol for Anki Overdrive vehicles. It is assumed that the reader already understands the basics of the protocol and can read C-style structs. Except when mentioned otherwise, only the payload is described. The packet header should be added as always.

SET_LIGHTS and SET_LIGHT_PATTERN fill the same nieche. In fact, SET_LIGHT_PATTERN can be used to achieve anything that SET_LIGHTS can and more. Imagine SET_LIGHTS as a selection of presets used in gameplay. We will go over SET_LIGHTS first as it is less complicated and was also the first packet I solved.

SET_LIGHTS

The SET_LIGHTS packet enables, disables or preserves the state of four different lighting presets. At its core, the payload struct looks like this:

struct set_lights_payload {
  uint8_t bitmask;
};

This rather impenetrable 8-bit value can be further split into 4-bit nibbles. Each bit pair in the nibbles is matched to a channel like this: ABCD ABCD where the channels A, B, C, and D correspond to the following light settings:

  • A -> Brakelights (Flickering Red)
  • B -> Headlights (Flickering Red & Green)
  • C -> Brakelights (Solid Red)
  • D -> Engine (does not seem to do anything; may need further investigation)

A channel's state is only changed if its bit in the lower nibble is set. If it is set, the bit in the high channel corresponds to whether it is enabled or disabled. For example, the bitmask 0010 0010 turns on the brakelights. 0010 0000 or 0000 0000 do not have any effect. If the light was on, it stays on. If the light is off, it stays off.

Lastly, it's important to note that channel A and C address the same lights. If both are set in the same packet, channel A always takes priority. E.g. 0010 1010 will result in the brakelights being disabled. 1010 1010 results in the brakelights flickering.

SET_LIGHT_PATTERN

Set light pattern allows detailed control of every light on the vehicle. A single pattern struct looks like this:

enum light_channel {
  engine_red = 0, tail = 1, engine_blue = 2, engine_green = 3, front_red = 4, front_green = 5
};

enum light_effect {
  // Sets the light to a steady, unchanging brightness specified in <start>
  steady = 0,
  // Fade from <start> to <end>, repeating (triangle wave)
  fade = 1,
  // Fade from <start> to <end> and back to <start>, repeating
  throb = 2,
  // Flashes according to <start> and <end> and <cycles_per_10s>. 
  // I do not yet comprehend this effect. Needs further analysis.
  flash = 3,
  // Flash randomly, regardless of <start> and <end>
  random = 4
};

struct light_pattern {
  enum light_channel channel;
  enum light_effect effect;
  uint8_t start;
  uint8_t end;
  uint8_t cycles_per_10s;
}

start and end are integers from 0 to 14 (both inclusive), where 14 is the maximum brightness the LED allows and 0 is off. cycles_per_10s has a universal application. It represents the amount of cycles the animation finishes in 10s. start=14,end=0,cycles_per_10s=2 for example will cause the light to fade from maximum brightness to off within 5 seconds.

A single SET_LIGHTS_PATTERN payload may contain at most 3 light patterns. Consequently the struct looks as follows:

struct set_light_pattern_payload {
  uint8_t channels;
  struct light_pattern patterns[3];
}

The payload may be padded to have a constant size, but this is not required. As before, any channel not mentioned in the payload will maintain its state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment