API Reference
Controlling the supercars
Controller
- class anki.Controller(*, timeout: float = 10)
This object controls all vehicle connections. With it you can connect to any number of vehicles and disconnect cleanly.
- Parameters:
timeout –
floatThe time until the controller gives up searching for a vehicle.
- async connect_many(amount: int, vehicle_ids: Collection[int | None] | None = None) tuple[anki.control.vehicle.Vehicle, ...]
Connect to <amount> non-charging Supercars
- Parameters:
amount –
intThe amount of vehicles to connect tovehicle_ids –
Optional[Iterable[int]]The vehicle ids passed to theVehicleinstances
- Returns:
The connected supercars
- Return type:
tuple[Vehicle]- Raises:
ValueError – The amount of requested supercars does not match the length of :param vehicle_ids:
VehicleNotFound – No supercar was found in the set timeout
ConnectionTimedoutException – A connection attempt to one of the supercars timed out
ConnectionDatabusException – A databus error occured whilst connecting to a supercar
ConnectionFailedException – A generic error occured whilst connecting to a supercar
RuntimeError – A vehicle with the specified id already exists. This will only be raised when using a custom id.
- async connect_one(vehicle_id: int | None = None) Vehicle
Connect to one non-charging Supercar and return the Vehicle instance
- Parameters:
vehicle_id –
Optional[int]The id given to theVehicleinstance on connection- Returns:
The connected supercar
- Return type:
- Raises:
VehicleNotFound – No supercar was found in the set timeout
ConnectionTimedoutException – The connection attempt to the supercar did not succeed within the set timeout
ConnectionDatabusException – A databus error occured whilst connecting to the supercar
ConnectionFailedException – A generic error occured whilst connection to the supercar
RuntimeError – A vehicle with the specified id already exists. This will only be raised when using a custom id.
- async connect_specific(address: str, vehicle_id: int | None = None) Vehicle
Connect to a supercar with a specified MAC address
- Parameters:
address –
strThe MAC-address of the vehicle to connect to. Needs to be uppercase seperated by colonsvehicle_id –
intThe id passed to theVehicleobject on its creation
- Returns:
The connected supercar
- Return type:
- Raises:
VehicleNotFound – No supercar was found in the set timeout
ConnectionTimedoutException – The connection attempt to the supercar did not succeed within the set timeout
ConnectionDatabusException – A databus error occured whilst connecting to the supercar
ConnectionFailedException – A generic error occured whilst connection to the supercar
RuntimeError – A vehicle with the specified id already exists. This will only be raised when using a custom id.
- async disconnect_all()
Disconnects from all the connected supercars
- Raises:
DisconnectTimedoutException – A disconnection attempt timed out
DisconnectFailedException – A disconnection attempt failed for unspecific reasons
- async scan(scan_vehicle: ~anki.control.vehicle.Vehicle | None = None, /, align_pre_scan: bool = True, scanner_class: type[anki.control.scanner.BaseScanner] = <class 'anki.control.scanner.Scanner'>) list[anki.misc.track_pieces.TrackPiece]
Assembles a digital copy of the map and adds it to every connected vehicle.
- Parameters:
scan_vehicle –
Optional[Vehicle]When passed a Vehicle object, this Vehicle will be used as a scanner. Otherwise one will be selected automatically.align_pre_scan –
boolWhen set to True, the supercars can start from any position on the map and align automatically before scanning. Disabling this means your supercars need to start between START and FINISHscanner_class –
typeThe type of scanner used
- Returns:
The resulting map
- Return type:
list[TrackPiece]- Raises:
DuplicateScanWarning – The map was already scanned in. This scan will be skipped.
Vehicle
- class anki.Vehicle(id: int, device: BLEDevice, client: BleakClient | None = None, controller: Controller | None = None, *, battery: BatteryState)
This class represents a supercar. With it you can control all functions of said supercar.
- Parameters:
id –
intThe id of theVehicleobjectdevice –
bleak.BLEDeviceThe BLE device representing the supercarclient –
Optional[bleak.BleakClient]A client wrapper around the BLE device
Note
You should not create this class manually, use one of the connect methods in the
Controller.- async align(speed: int = 300, *, target_previous_track_piece_type: TrackPieceType = TrackPieceType.FINISH)
Align to the start piece.
- Parameters:
speed –
intThe speed the vehicle should travel at during alignment
- battery_change(func: Callable[[], None])
Register a callback to execute on changes to the battery state.
Note
It is not guaranteed that the battery state has actually changed from the last callback. Further note that this function is not called on startup.
- Raises:
ValueError – The function passed is not an event handler
- property battery_state: BatteryState
The state of the supercar’s battery
- async change_lane(lane: BaseLane, horizontalSpeed: int = 300, horizontalAcceleration: int = 300, *, _hopIntent: int = 0, _tag: int = 0)
Change to a desired lane
- Parameters:
Note
Due to a hardware limitation vehicles won’t reliably perform lane changes under 300mm/s speed.
- async change_position(roadCenterOffset: float, horizontalSpeed: int = 300, horizontalAcceleration: int = 300, *, _hopIntent: int = 0, _tag: int = 0)
Change to a position offset from the track centre
- Parameters:
roadCenterOffset –
floatThe target offset from the centre of the track piece in mmhorizontalSpeed –
intThe speed the vehicle will move along the track at in mm/shorizontalAcceleration –
intThe acceleration in mm/s² the vehicle will move horizontally with
Note
Due to a hardware limitation vehicles won’t reliably perform lane changes under 300mm/s speed.
- async connect()
Connect to the Supercar Don’t forget to call Vehicle.disconnect on program exit!
- Raises:
ConnectionTimedoutException – The connection attempt to the supercar did not succeed within the set timeout
ConnectionDatabusException – A databus error occured whilst connecting to the supercar
ConnectionFailedException – A generic error occured whilst connection to the supercar
- property current_track_piece: TrackPiece | None
The
TrackPiecethe vehicle is currently located atNote
This will return
Noneif either scan or align is not completed
- delocalized(func: Callable[[], None])
A decorator marking this function to be execute when the vehicle has delocalized*.
- Parameters:
func –
functionThe listening function
Note
It is not guaranteed that the handler will be called when the vehicle is delocalized. Furthermore, it is not guaranteed that the handler will not be called when the vehicle is still localized. This method should only be used for informational purposes!
- async disconnect() bool
Disconnect from the Supercar
Note
Remember to execute this for every connected
Vehicleonce the program exits. Not doing so will result in your supercars not connecting sometimes as they still think they are connected.- Returns:
boolThe connection state of the
Vehicleinstance. This should always be False
- Raises:
DisconnectTimedoutException – The attempt to disconnect from the supercar timed out
DisconnectFailedException – The attempt to disconnect from the supercar failed for an unspecified reason
- get_lane(mode: type[_Lane]) _Lane | None
Get the current lane given a specific lane type
- Parameters:
mode –
BaseLaneA class such asLane3orLane4inheriting fromBaseLane. This is the lane system being used- Returns:
The lane the vehicle is on. This may be none if no lane information is available (such as at the start of the program, when the vehicles haven’t moved much)
- Return type:
Optional[BaseLane]
- property is_connected: bool
True if the vehicle is currently connected
- property map: tuple[anki.misc.track_pieces.TrackPiece, ...] | None
The map the
Vehicleinstance is using. This isNoneif theVehicledoes not have a map supplied.
- property map_position: int | None
The position of the
Vehicleinstance on the map. This isNoneifVehicle.align()has not yet been called.
- async ping()
Send a ping to the vehicle
- pong(func)
A decorator marking an function to be executed when the supercar responds to a ping
- Parameters:
func –
functionThe function to mark as a listener- Returns:
The function being passed in
- Return type:
function
- remove_delocalized_watcher(func: Callable[[], None])
Remove a delocalization event handler that was added by
Vehicle.delocalized().- Parameters:
func –
functionThe function to be removed- Raises:
ValueError – The function passed is not an event handler
- remove_track_piece_watcher(func: Callable[[], None])
Remove a track piece event handler added by
Vehicle.track_piece_change()- Parameters:
func –
functionThe function to remove as an event handler- Raises:
ValueError – The function passed is not an event handler
- property road_offset: float | None
The offset from the road centre. This is
Noneif the supercar did not send any information yet. (Such as when it hasn’t moved much)
- async set_light_pattern(r: int, g: int, b: int)
Set the engine light (the big one) at the top of the vehicle
Warning
This function is deprecated due to a hardware bug causing it not to function. It will not execute.
- async set_lights(light: int)
Set the lights of the vehicle in accordance with a bitmask
Warning
This function is deprecated due to not functioning properly. It will not execute.
- async set_speed(speed: int, acceleration: int = 500)
Set the speed of the Supercar in mm/s
- Parameters:
speed –
intThe speed in mm/sacceleration –
Optional[int]The acceleration in mm/s²
- property speed: int
The speed of the supercar in mm/s. This is
Noneif the supercar has not moved orVehicle.setSpeed()hasn’t been called yet.
- async stop()
Stops the Supercar
- track_piece_change(func: Callable[[], None])
A decorator marking a function to be executed when the supercar drives onto a new track piece
- Parameters:
func –
functionThe listening function- Returns:
The function that was passed in
- Return type:
function
- async turn(type: int = 3, trigger: int = 0)
Warning
This does not yet function properly. It is advised not to use this method
- async wait_for_track_change() TrackPiece | None
Waits until the current track piece changes.
- Returns:
The new track piece. None if
Vehicle.map()is None (for example if the map has not been scanned yet)- Return type:
Scanner
- class anki.control.scanner.Scanner(vehicle: Vehicle)
A scanner object performs a simple map scan without any alignment.
- Parameters:
vehicle –
VehicleThe vehicle to perform the scan with
- async align(vehicle: Vehicle, *, target_previous_track_piece_type: TrackPieceType = TrackPieceType.FINISH) None
Aligns a vehicle to the START piece
- Parameters:
vehicle –
VehicleThe vehicle to align
- async scan() list[anki.misc.track_pieces.TrackPiece]
Perform the scan
Custom Scanning
- class anki.control.scanner.BaseScanner(vehicle: Vehicle)
Abstract base class for all custom scanners. Any subclasses of this must override the methods
BaseScanner.scan()BaseScanner.align().- Parameters:
vehicle –
VehicleThe vehicle used for the scanning operation.
- abstract async align(vehicle: Vehicle, *, target_previous_track_piece_type: TrackPieceType = TrackPieceType.FINISH) None
This method should be used to align a vehicle to the START piece. It is required for this method to work without a functional scan.
- Parameters:
vehicle –
VehicleThe vehicle to be aligned.
- abstract async scan() list[anki.misc.track_pieces.TrackPiece]
This method should scan in the map using various functionalities. The returned list of track pieces should begin with a type of TrackPieceType.START and end with TrackPieceType.FINISH.
- Returns:
The scanned map
- Return type:
list[TrackPiece]
Vehicle models
BatteryState
- class anki.control.vehicle.BatteryState(full_battery: bool, low_battery: bool | None, on_charger: bool, charging: bool | None = None)
Represents the state of a supercar
- classmethod from_charger_info(payload: bytes)
Constructs a
BatteryStateinstance from a CHARGER_INFO message.- Parameters:
payload –
bytesThe payload of the CHARGER_INFO message- Returns:
The new
BatteryStateinstance
- classmethod from_int(state: int)
Constructs a
BatteryStatefrom an integer representation- Parameters:
state –
intThe integer state passed by the discovery process- Returns:
The new
BatteryStateinstance
Lights
Track models
TrackPiece
- class anki.TrackPiece(loc: int, type: TrackPieceType, clockwise: bool)
This class represents the different pieces of the track. It includes the type of the track piece and whether or not it turns clockwise.
You should not be creating these manually.
- Parameters:
loc –
intThe loc value send by the supercar. I’m not sure what it means eithertype –
TrackPieceTypeThe type of track piececlockwise –
boolWhether or not this track piece turns in a clockwise direction
TrackPieceType
- enum anki.TrackPieceType(value)
An enumerator for all supported track piece types.
Thank you to https://github.com/BerndMuller/JAnki/
Valid values are as follows:
- START = <TrackPieceType.START: [33]>
- FINISH = <TrackPieceType.FINISH: [34]>
- STRAIGHT = <TrackPieceType.STRAIGHT: [36, 39, 40, 48, 51]>
- CURVE = <TrackPieceType.CURVE: [17, 18, 20, 23, 24, 27]>
- INTERSECTION = <TrackPieceType.INTERSECTION: [10]>
- LAUNCH_START = <TrackPieceType.LAUNCH_START: [43]>
Lane support
BaseLane
- class anki.BaseLane(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
The base class for all Lanes. This class does not provide any lanes of its own, but can be inherited from to create your own lane system. Pre-configured children of this class are
Lane3andLane4- classmethod by_name(name: str)
Get a lane by the lane’s name.
- Parameters:
name –
strThe name of the lane- Raises:
ValueError – The name passed does not refer to an existing lane
- classmethod get_closest_lane(position: float) Self
Returns the lane closest to the entered position.
- Parameters:
position –
floatThe position offset from the centre of the road in millimetres.- Raises:
RuntimeError – The this method is being called with does not have any specified lanes.
Lane3
Lane4
- enum anki.Lane4(value)
A lane class that supports 4 different lanes. Values indicate the millimetre distance from the road centre.
- Member Type:
float
Valid values are as follows:
- LEFT_2 = <Lane4.LEFT_2: -60.0>
- LEFT_1 = <Lane4.LEFT_1: -30.0>
- RIGHT_1 = <Lane4.RIGHT_1: 30.0>
- RIGHT_2 = <Lane4.RIGHT_2: 60.0>
Exceptions
- exception anki.errors.AnkiError
Base class for all errors raised by this library
- exception anki.errors.ConnectionDatabusError
A data-bus error occured whilst connecting to the vehicle
- exception anki.errors.ConnectionFailedError
Could not connect to the vehicle
- exception anki.errors.ConnectionTimedoutError
The attempt to connect with the vehicle timed out
- exception anki.errors.DisconnectFailedError
The attempt to disconnect from the vehicle failed
- exception anki.errors.DisconnectTimedoutError
The disconnect attempt timed out
- exception anki.errors.DuplicateScanWarning
The map has already been scanned, but scan has been called anyway. This is not dangerous, but unneccessary
- exception anki.errors.MalformedPacketWarning
Received package did not conform to the Protocol. See https://anki.github.io/drive-sdk/docs/programming-guide
- exception anki.errors.TrackPieceDecodeWarning
The TrackPiece received from the vehicle was invalid
- exception anki.errors.VehicleNotFoundError
Could not find a Supercar