spike.scenario package

Submodules

spike.scenario.abaqus module

Class providing abaqus for robot behaviour

class spike.scenario.abaqus.ScenarioAbaqus

Bases: object

Class storing a robot abaqus The abaqus is provided as an excel workbook linking an input to one or more values. The abaqus topics are derived from the workbook sheet headers

__init__()

Constructor

read(filename, sheet)

Load an abaqus from an input workbook sheet content

Parameters:
  • filename (string) – name of the workbook file to read data from

  • sheet (string) – name of the workbook sheet containing the abaqus

get(topic, command)

Get abaqus value for a given command

Parameters:
  • topic (string) – command topic

  • command (integer) – command value

Returns:

topic value for the given command.

Return type:

float

spike.scenario.commands module

Software component commands management

class spike.scenario.commands.ScenarioCommands

Bases: object

Class managing robot command and their impact on dynamics

s_shared_timer = <spike.scenario.timer.ScenarioTimer object>
__init__()

Constructor

reset()

Commands reset function

configure(dynamics)

Configuration function for command

Parameters:

dynamics (ScenarioDynamics) – robot dynamic data to update from command

give(component, name, args)

Register a new command being given to the hub

Parameters:
  • component (object (Button, ColorSensor,...)) – the software component at the origin of the command

  • name (string) – command name

  • args (dictionary) – command parameters

Raises:

ValueError – Command not known

Returns:

command to perform

Return type:

generator function

__statuslight_on(component, args)

Process StatusLight “on” command

__statuslight_off(component)

Process StatusLight “off” command

__colorsensor_light_up(component, args)

Process StatusLight light up commands

__lightmatrix_show_image(component, args)

Process LightMatrix show image command

__lightmatrix_set_pixel(component, args)

Process LightMatrix set pixel command

__lightmatrix_write(component, args)

Process LightMatrix write command

__lightmatrix_off(component)

Process LightMatrix off command

__speaker_beep(component, args)

Process StatusLight beep command

__speaker_start_beep(component, args)

Process StatusLight start beep command

__speaker_stop(component)

Process StatusLight stop command

__speaker_set_volume(component, args)

Process StatusLight set volume command

__motorpair_set_stop_action(component, args)

Process MotorPair set stop action command

__motor_set_stall_detection(component, args)
__motor_set_stop_action(component, args)

spike.scenario.components module

Software component registration management

class spike.scenario.components.ScenarioComponents

Bases: object

Class managing all registered software components and their update along time

s_logger = <Logger components (WARNING)>
__init__()

Constructor

reset()

reset method

configure(model)

Configure components from robot ground truth

Parameters:

model (ScenarioModel) – robot static description

register(component, port1, port2)

Register a software component associated with the robot

Parameters:
  • component (object (Button, ColorSensor,...)) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

Raises:

ValueError – unknown component type

update_from_data(time, data)

Update component from synthetic data

Parameters:
  • time (float) – current time

  • data (ScenarioData) – data to use to update components states

update_from_mecanics(time, dynamics)

Update component from robot dynamic data

Parameters:
  • time (float) – current time

  • dynamics (ScenarioDynamics) – robot dynamic state

__register_motor(component, port1, port2)

Check if motor software component can be allocated Atomic operation

Parameters:
  • component (Motor) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

Raises:

ValueError – Missing port or too many ports provided or unexisting port or port does not host a Motor or Motor already created on port

__register_motorpair(component, port1, port2=None)

Check if motorpair software component can be allocated Atomic operation

Parameters:
  • component (MotorPair) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

Raises:

ValueError – Single motors not created on port or motorpair already created

__register_colorsensor(component, port1, port2)

Check if color sensor software component can be allocated Atomic operation

Parameters:
  • component (ColorSensor) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

Raises:

ValueError – Missing port or too many ports provided or unexisting port or port does not host a ColorSensor or ColorSensor already created on port

__register_forcesensor(component, port1, port2)

Check if force sensor software component can be allocated Atomic operation

Parameters:
  • component (ForceSensor) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

Raises:

ValueError – Missing port or too many ports provided or unexisting port or port does not host a ForceSensor or ForceSensor already created on port

__register_distancesensor(component, port1, port2)

Check if distance sensor software component can be allocated Atomic operation

Parameters:
  • component (DistanceSensor) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

Raises:

ValueError – Missing port or too many ports provided or unexisting port or port does not host a DistanceSensor or DistanceSensor already created on port

__register_button(component, port1, port2)

Check if button software component can be allocated Atomic operation

Parameters:
  • component (Button) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

Raises:

ValueError – Missing side or too many sides provided or unknown side or Button already created on side

__register_lightmatrix(component, port1, port2)

Check if light matrix software component can be allocated LightMatrix is part of the hub and not connected to a hub port Atomic operation

Parameters:
  • component (LightMatrix) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

Raises:

ValueError – port provided or LightMatrix already created

__register_motion_sensor(component, port1, port2)

Check if motion sensor software component can be allocated MotionSensor is part of the hub and not connected to a hub port Atomic operation

Parameters:
  • component (MotionSensor) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

Raises:

ValueError – port provided or MotionSensor already created

__register_speaker(component, port1, port2=None)

Check if speaker software component can be allocated Speaker is part of the hub and not connected to a hub port Atomic operation

Parameters:
  • component (Speaker) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

Raises:

ValueError – port provided or Speaker already created

__register_statuslight(component, port1, port2=None)

Check if status light software component can be allocated StatusLight is part of the hub and not connected to a hub port Atomic operation

Parameters:
  • component (StatusLight) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

Raises:

ValueError – port provided or StatusLight already created

__register_timer(port1, port2=None)

Check if timer software component can be allocated Timer can always be created and is not associated to a hub port Atomic operation

Parameters:
  • component (MotionSensor) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

Raises:

ValueError – port provided

spike.scenario.data module

Scenario data management

class spike.scenario.data.ScenarioData

Bases: object

Class managing simulation data

s_time_header = 'time'
s_invalid_value = -1e+16
__init__()

Contructor for each instantiation / do nothing

configure(filename, sheet)

Read scenario data from excel file

Parameters:
  • filename (string) – path to excel file in which the scenario data are located

  • sheet (string) – sheet from which data shall be retrieved

extrapolate(header, time)

Extrapolate a given data at a given time

Parameters:
  • header (string) – header of the data to extrapolate

  • time (float) – extrapolation date in seconds

Raises:

ValueError – header not found in data

Returns:

The extrapolated value at the input time

Return type:

depending on data type

is_loaded()

Loaded status return function :

Returns:

True if data are loaded, False otherwise

Return type:

boolean

__load_data(sheet)

Reads data from the excel sheet

Parameters:

sheet (string) – sheet to read object status from

spike.scenario.dynamics module

Robot dynamic state management

class spike.scenario.dynamics.ScenarioDynamics(model, mat=None)

Bases: object

Robot dynamics modelisation

s_shared_timer = <spike.scenario.timer.ScenarioTimer object>
s_logger = <Logger dynamics (WARNING)>
__init__(model, mat=None)

Constructor

Parameters:
reset()

Reset function

configure(coordinates=None)

Configure dynamics

Parameters:

coordinates (dictionary {'north', 'east', 'yaw'}) – initial robot coordinates, default is None

current()

Current robot dynamic status accessor

Returns:

current robot dynamics measurements

Return type:

dictionary

move

Dispatch methods based on type signature

See Also:

Dispatcher

start_tank

Dispatch methods based on type signature

See Also:

Dispatcher

move_tank

Dispatch methods based on type signature

See Also:

Dispatcher

start_tank_at_power

Dispatch methods based on type signature

See Also:

Dispatcher

set_degrees_counted(port, degrees)

Single motor set_degrees_counted function

Parameters:
  • port (string) – motor port

  • degrees (integer) – the number of degrees to set

Raises:

RuntimeError – The port is not associated to a motor

run_to_position

Dispatch methods based on type signature

See Also:

Dispatcher

run_to_degrees_counted

Dispatch methods based on type signature

See Also:

Dispatcher

run_for_rotations

Dispatch methods based on type signature

See Also:

Dispatcher

run_for_degrees

Dispatch methods based on type signature

See Also:

Dispatcher

run_for_seconds

Dispatch methods based on type signature

See Also:

Dispatcher

start

Dispatch methods based on type signature

See Also:

Dispatcher

start_at_power

Dispatch methods based on type signature

See Also:

Dispatcher

stop

Dispatch methods based on type signature

See Also:

Dispatcher

extrapolate(time)

Extrapolate robot status at a given date

Parameters:

time (float (seconds)) – extrapolation date

__compute_motor_speeds_from_steering(steering, speed)

Compute left and right motors command from steering and speed The behavior of this function, with a discontinuities between 99% and 100% as been validated by experiment using spike motors

Parameters:
  • steering (integer [-100,100]) – the direction and quantity to steer the Driving Base.

  • steering – the speed at which the Driving Base will move while performing a curve.

Returns:

motor left and right command

Return type:

dictionary

__update_kinematics()

Update robot global kinematics from motor speeds

__check_pair(left, right)

Check if left and right ports connects pairable motors

Parameters:
  • left (string) – left motor port

  • right (boolean) – right motor port

Returns:

True if motors are pairable, False otherwise

Raises:

RuntimeError – No motor in input ports or motor can not be paired

__check_configuration(coordinates)

Check input json configuration

Parameters:

conf (dictionary) – configuration file content

Raises:

ValueError – Missing north, east or yaw coordinates

__modulo_dir(angle)

Degrees to radians transformation

Parameters:

input (float (radians)) – angle

Returns:

angle

Return type:

float (degrees) [-180,180]

spike.scenario.ground module

Scenario ground management

class spike.scenario.ground.ScenarioGround

Bases: object

Scene mat modelling

s_logger = <Logger ground (WARNING)>
__init__()

Constructor

configure(conf, path)

Configure dynamics

Parameters:
  • conf (dictionary) – ground configuration

  • path (string) – configuration file path

get_color(north, east)

Get color from position on mat

Parameters:
  • north (float) – north coordinate in centimeters

  • east (float) – east coordinate in centimeters

__check_configuration(conf)

Check input json configuration

Parameters:

conf (dictionary) – configuration file content

Raises:

ValueError – missing image or scale information

spike.scenario.model module

Classes describing lego robot static structure

class spike.scenario.model.ScenarioModel

Bases: object

Class modelling robot static relative geometry

s_topics = ['design', 'abaqus', 'components']
s_parts_to_connect = ['Motor', 'ColorSensor', 'DistanceSensor', 'ForceSensor']
s_ports = ['A', 'B', 'C', 'D', 'E', 'F']
s_logger = <Logger model (WARNING)>
__init__()

Constructor

configure(filename)

Configure robot

Parameters:

filename (string) – Robot configuration file path

Raises:

ValueError – Component not found for port, component type does not match ldraw type or 2 parts connected to the same hub port or missing attribute for component or missing robot design file or missing ldraw unit size or unknown topic in configuration file

altitude()

Returns the robot wheels center altitude in NED local reference

Returns:

robot altitude

Return type:

float (cm)

ports()

Returns the allocated ports with their part type

Returns:

ports associated with their components

Return type:

dictionary

by_port()

Returns the robot parts indexed by port

Returns:

robot parts

Return type:

dictionary

by_type()

Returns the robot parts indexed by type

Returns:

robot parts

Return type:

dictionary

all()

Returns the robot active or sensive parts

Returns:

robot parts

Return type:

list

__check_configuration(conf)

Check input json configuration

Parameters:

conf (dictionary) – configuration file content

Raises:

ValueError – missing attribute for component or missing robot design file or missing ldraw unit size or unknown topic in configuration file

__read(filename, ldu=0.04)

Build robot model from ldraw file

Parameters:
  • filename (string) – ldraw formatted filename path

  • ldu (float) – ldu (ldraw unit) size in centimeters, default 0.4 mm

Returns:

robot parts, robot model, ldraw parts

Return type:

list, list, dictionary

__convert_pose(parts, system)

Convert part pose in a new coordinates system

Parameters:
  • parts (list) – robot parts with pose in ldraw reference

  • system (CoordinateSystem) – coordinate system to transform parts into

Returns:

converted parts

Return type:

list

__add_port_to_parts(conf, parts)

Add hub ports info to parts from the robot configuration file. Extract wheel spins info for further use

Parameters:
  • conf (dictionary) – robot configuration file content

  • parts (list) – robot parts

Raises:

ValueError – Component not found for port, component type does not match ldraw type or 2 parts connected to the same hub port

Returns:

parts, wheel spins

Return type:

tuple (list, dictionary)

__organize_parts(parts, spins)

Organize parts to be accessible by port or by type

Parameters:
  • parts (list) – list of parts to organize

  • spins (dictionary) – wheel spins already extracted from the configuration file

Returns:

extended parts, parts by type, parts by port

Return type:

tuple (list, dictionary, dictionary)

Raises:

ValueError – Can not manage other than 2 wheels

spike.scenario.parts module

Classes describing lego robot component parts https://www.ldraw.org/article/218.html and their dynamic data

class spike.scenario.parts.ScenarioPart(copy=None)

Bases: object

Class gathering data on a robot part

s_logger = <Logger parts (WARNING)>
__init__(copy=None)

Constructor

Parameters:

copy (ScenarioPart) – part to copy if copy constructor, None (default) otherwise

property type

Part type getter

Returns:

part type

Return type:

string

property id

Part identifier getter

Returns:

part ldraw identifier

Return type:

string

property pose

Part 3d absolute pose getter

Returns:

part absolute pose

Return type:

Pose3d

property relative

Part 3d relative pose getter

Returns:

part 3d relative pose

Return type:

Pose3d

property port

Part port getter

Returns:

part port, None if the component is not connected

Return type:

string

property color

Part color getter

Returns:

part color

Return type:

string

export()

Export part as end-user dict

Returns:

part representation from the user perspective

Return type:

dictionary

derive_relative(center)

Compute part pose relative to the robot center pose

Parameters:

center (Pose3d) – robot center relative pose

derive_pose(center)

Compute part absolute pose from the robot center absolute pose

Parameters:

center (Pose3d) – robot center absolute pose

class spike.scenario.parts.ScenarioPartMotor(part)

Bases: ScenarioPart

Class defining motor dynamics part

s_speed_abaqus = <spike.scenario.abaqus.ScenarioAbaqus object>
s_ids = ['54696', '54675']
static configure(filename, sheet)

Static method to load speed abaqus from file

Parameters:
  • filename (string) – workbook to read abaqus from

  • sheet (string) – workbook sheet to read abaqus from

__init__(part)

Motor constructor

:param part : part to set as motor :type part : ScenarioPart object

Raises:

ValueError – part is not a known motor

reset()

Part dynamic data reset function

property speed

Rotation speed getter

Returns:

motor rotation speed

Return type:

float (rads-1)

property degrees

degrees getter

Returns:

motor displacement degrees

Return type:

float (radians)

property wheel

Wheel getter

Returns:

motor associated wheel, None if motor is not connected to a wheel

Return type:

ScenarioPartWheel

property clockwise

Returns the direction of the displacement induced by clockwise rotation

Returns:

-1 if clockwise rotation means moving backwards, 1 otherwise

Return type:

integer

export()

Export motor as end-user dict

Returns:

dictionary representing the motor from the user perspective

Return type:

dictionary

command(command, direction='clockwise')

Derive motor rotation speed from command

Parameters:
  • command (integer [-100,100]) – motor command

  • direction (string (clockwise or counterclockwise)) – motor rotation direction

radius()

Access wheel radius if motor is connected to a wheel

Returns:

wheel radius (None if motor is not linked to a wheel)

Return type:

float

side()

Access wheel side if motor is connected to a wheel

Returns:

wheel side (None if motor is not linked to a wheel)

Return type:

str (left or right)

is_pairable(other)

Check if 2 motors are pairables

Parameters:

other (ScenarioPartMotor) – other motor to pair

Returns:

True if motors can be paired, False otherwise

Return type:

boolean

extrapolate(delta)

Extrapolate motor angular displacement from time difference

Parameters:

delta (float) – time period in seconds

class spike.scenario.parts.ScenarioPartWheel(part, motor, spin)

Bases: ScenarioPart

Class defining wheel dynamics

s_wheel_radius_abaqus = <spike.scenario.abaqus.ScenarioAbaqus object>
s_ids = ['39367PB01', '49295C01', '32020C01']
s_sides = ['left', 'right']
static configure(filename, sheet)

Static method to load speed abaqus from file

Parameters:
  • filename (string) – workbook to read abaqus from

  • sheet (string) – workbook sheet to read abaqus from

__init__(part, motor, spin)

Constructor

Parameters:
  • part (ScenarioPartMotor) – part to set as sheel

  • part – motor associated to the wheel

  • spin – 1 if the wheel rotates in the same direction as its motor (even number of gears), -1 otherwise (odd number of gears)

Raises:

ValueError – part is not a known wheel

property side

Wheel side getter

Returns:

wheel side on robot

Return type:

string (left, right)

property radius

Wheel radius getter

Returns:

wheel radius

Return type:

float (cm)

property speed

Wheel linear speed getter

Returns:

wheel linear

Return type:

float (cms-1)

set_side(other)

Set wheel side on model

Parameters:

other (ScenarioPartWheel) – other wheel to compare for left/right

export()

Export wheel as end-user dict

Returns:

dictionary representing the wheel from the user perspective

Return type:

dictionary

distance(wheel)

Compute distance between 2 wheels

Parameters:

wheel (ScenarioPartWheel) – other wheel to analyse

Returns:

distance between the 2 wheels

Return type:

float (cm)

class spike.scenario.parts.ScenarioPartColorSensor(part)

Bases: ScenarioPart

Class color sensor dynamics part

s_logger = <Logger parts (WARNING)>
s_ids = ['37308C01']
__init__(part)

Color sensor constructor

Parameters:

part (ScenarioPart) – part to set as motor

Raises:

ValueError – part is not a known color sensor

export()

Export wheel as end-user dict

Returns:

dictionary representing the wheel from the user perspective

Return type:

dictionary

read_color(mat)

Read color at sensor position on mat

Parameters:

mat (ScenarioGround) – mat model

class spike.scenario.parts.ScenarioPartHub(part)

Bases: ScenarioPart

Class hub dynamics part

s_logger = <Logger parts (WARNING)>
s_ids = ['BB1142C01']
__init__(part)

Hub constructor

Parameters:

part (ScenarioPart) – part to set as hub

Raises:

ValueError – part is not a known hub

class spike.scenario.parts.ScenarioPartForceSensor(part)

Bases: ScenarioPart

Class force sensor dynamics part

s_logger = <Logger parts (WARNING)>
s_ids = ['37312C01']
__init__(part)

Force sensor constructor

Parameters:

part (ScenarioPart) – part to set as force sensor

Raises:

ValueError – part is not a known force sensor

class spike.scenario.parts.ScenarioPartDistanceSensor(part)

Bases: ScenarioPart

Class distance sensor dynamics part

s_logger = <Logger parts (WARNING)>
s_ids = ['37316C01']
__init__(part)

Distance sensor constructor

Parameters:

part (ScenarioPart) – part to set as distance sensor

Raises:

ValueError – part is not a known distance sensor

spike.scenario.scenario module

Simulation scenario management API

class spike.scenario.scenario.ScenarioThreadData

Bases: object

Shared data for robot update thread

s_shared_timer = <spike.scenario.timer.ScenarioTimer object>
s_modes = ['read', 'compute']
s_logger = <Logger scenario (NOTSET)>
__init__()

Constructor

reset()

Reset function

reinitialize()

Scenario reinitialization function Keeps registered software components but reinitialize dynamics

configure(scenario, robot, sheet=None, logger=None)

Configuration function

Parameters:
  • scenario (string) – scenario configuration file path

  • robot (string) – robot configuration file path

  • sheet (string) – name of the sheet to use for component data feeding

  • logger (string) – logging configuration file path

Raises:

ValueError – missing information, initial coordinates or workbook sheet or unknown data mode

register_component(component, port1, port2)

Register a software component associated with the robot

Parameters:
  • component (object (Button, ColorSensor,...)) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

is_started()

Check if the processing is started

Returns:

True if the processing is started, False otherwise

Return type:

boolean

step()

Step into time

command(component, name, args)

Add new command to process

Parameters:
  • component (object (Button, ColorSensor,...)) – the software component at the origin of the command

  • name (string) – command name

  • args (dictionary) – command parameters

Returns:

command to perform

Return type:

generator function

get_status()

Return current robot status

Returns:

the current robot status processed by the thread

Return type:

dictionary

get_components()

Return robot components

Returns:

the robot components

Return type:

list

set_shall_continue(value)

Shall continue setting function - Atomic function

Parameters:

value (boolean) – True if thread processing shall continue, false otherwise

shall_continue()

Shall continue accessor function - Atomic function

Returns:

True if thread processing shall continue, false otherwise

Return type:

boolean

run()

Thread data processing function

__check_configuration(conf, sheet)

Check input json configuration

Parameters:
  • conf (dictionary) – configuration file content

  • sheet (string) – workbook sheet to use for synthetic data

Raises:

ValueError – missing information, initial coordinates or workbook sheet or unknown data mode

class spike.scenario.scenario.Scenario

Bases: object

Singleton class managing the robot status

s_instance = <spike.scenario.scenario.Scenario object>
s_logger = <Logger scenario (NOTSET)>
s_init()

Constructor for singleton / only called once

__init__()

Contructor for each instantiation / do nothing

configure(scenario, robot, sheet=None)

Loading configuration from file

Parameters:
  • scenario (string) – path of json file to read scenario data from

  • robot (string) – path of json file describing robot configuration

  • sheet (string) – sheet to read scenario data from

register(component, port1=None, port2=None)

Register a software component associated with the robot

Parameters:
  • component (object (Button, ColorSensor,...)) – the software component initiated

  • port1 (string) – first port to check

  • port2 (string) – second port to check

start()

Robot starting function

step()

Step into time from a period set by configuation

command(component, name, args)

Process new robot command

Parameters:
  • component (object (Button, ColorSensor,...)) – the software component at the origin of the command

  • name (string) – command name

  • args (dictionary) – command parameters

Returns:

command to perform

Return type:

generator function

stop()

End scenario

reset()

Reset scenario — All components will be deregistered

status()

Return robot current status

Returns:

robot real status

Return type:

dictionary

components()

Return robot components list

Returns:

robot component lists

Return type:

list

spike.scenario.timer module

Generic timer singleton representing world time

class spike.scenario.timer.ScenarioTimer

Bases: object

Singleton providing world clock to all timers

s_instance = <spike.scenario.timer.ScenarioTimer object>
s_sleep_time = 0.01

Scenario measurements update frequency — Compliant with spike sensors frequency 100Hz

s_logger = <Logger time (WARNING)>
s_init()

Constructor for singleton / only called once

__init__()

Contructor for each instantiation / do nothing

reset()

World clock reset function

configure(configuration)

Configure world clock

Parameters:

configuration (dictionary (mode + parameters)) – configuration values

sleep()

Pause scenario according to time mode In controlled mode, the scenario shall sleep longer than the main thread to make sure no step is missed on the main thread part. In relatime mode, the scenario shall sleep less than the main thread to make sure the measurements are updated at each main thread call.

step()

Function that steps into time - controlled scenario only

time()

Clock time return function

Returns:

current time in the world

Return type:

float (seconds)

Module contents