World#

enum pyenki.World.WallsType(value)#

Describes the type of boundary walls.

Valid values are as follows:

SQUARE = <WallsType.SQUARE: 0>#

A rectangular boundary wall of size (pyenki.World.lx, pyenki.World.ly).

CIRCULAR = <WallsType.CIRCULAR: 1>#

A circular boundary wall of radius pyenki.World.radius.

NONE = <WallsType.NONE: 2>#

No boundary walls.

class pyenki.World.GroundTexture#

2-D Texture for ground stored as a ARGB array (0xAARRGGBB in little endian). Users should access class data using the buffer protocol, i.e.

>>> image = np.zeros((200, 100, 4), dtype=np.uint8)
>>> gt = World.GroundTexture(image)
>>> gt.width, gt.height
(100, 200)
>>> data = numpy.asarray(gt)
>>> data.shape, data[0, 0, 0]
((100, 200, 4), np.uint8(0))
width#

the width

Type:

int

height#

the height

Type:

int

__init__(*args, **kwargs)#

Overloaded function.

  1. __init__() -> None

Creates an empty ground texture

  1. __init__(data: Annotated[numpy.ArrayLike, numpy.uint8]) -> None

Creates an ground texture with a copy of the ARGB data

Parameters:

data (ARGBImage) – A numpy array of shape (height, width, 4) and type numpy.uint8 storing ARGB pixels.

class pyenki.World#

The world is the container of all objects and robots. It is either

  • a rectangular arena with walls at the borders:

    World(lx = ..., ly = ...)
    
  • a circular area with walls at the borders:

    World(radius = ...)
    
  • or an infinite surface with no walls:

    World()
    
Parameters:
  • lx (float) – The rectangular world x-size in centimeters

  • ly (float) – The rectangular world y-size in centimeters

  • radius (float) – The circular world radius in centimeters

  • walls_color (Color) – Optional wall color, default is Color.gray

  • ground_texture (World.GroundTexture | None) – Optional ground texture, default is an empty image.

  • seed (int) – The random seed

Example:

import pyenki

world = pyenki.World()
thymio = Thymio2()
world.add_object(thymio)
wall = pyenki.PhysicalObject(lx=10, ly=50, height=5, mass=1,
                             color=pyenki.Color(0.5, 0.3, 0.3))
world.add_object(wall)
# Run 100 times a 0.1 s long simulation step
for _ in range(100):
    world.step(0.1)
objects#

The list of all objects

Type:

list[PhysicalObject]

robots#

The list of all robots

Type:

list[Robot]

static_objects#

The list of all objects that are not robots

Type:

list[PhysicalObject]

control_step_callback#

A function called at each update step

def callback(World: world, time_step: bool) -> None: ...
Type:

Callable[[World, float], None] | None

random_generator#

The random generator

Type:

numpy.random.Generator

random_seed#

The random seed

Type:

int

lx#

the world x-size [cm]

Type:

float

ly#

the world y-size [cm]

Type:

float

radius#

the world radius [cm]

Type:

float

walls_type#

the type of boundary walls.

Type:

World.WallsType

ground_texture#

an optional image to color the ground (readonly).

Type:

World.GroundTexture

__init__(*args, **kwargs)#

Overloaded function.

  1. __init__(seed: SupportsInt = 0) -> None

  2. __init__(lx: SupportsFloat, ly: SupportsFloat, walls_color: pyenki.Color = Color(r=0.5, g=0.5, b=0.5, a=1.0), ground_texture: pyenki.World.GroundTexture | None = None, seed: SupportsInt = 0) -> None

  3. __init__(radius: SupportsFloat, walls_color: pyenki.Color = Color(r=0.5, g=0.5, b=0.5, a=1.0), ground_texture: pyenki.World.GroundTexture | None = None, seed: SupportsInt = 0) -> None

add_object(object: pyenki.PhysicalObject) None#

Add an object to the simulation.

Parameters:

object (PhysicalObject) – the object to add.

copy_random_generator(world: pyenki.World) None#

Copy the random generator from another world

Parameters:

world (World) – the other world.

get_ground_color(position: Vector) pyenki.Color#

Returns the color of the floor at a given position

Parameters:

position (Vector) – the position.

Returns:

the color at the position.

Return type:

Color

remove_object(object: pyenki.PhysicalObject) None#

Remove an object from the simulation.

Parameters:

object (PhysicalObject) – the object to remove.

render(walls_height: SupportsFloat = 10, width: SupportsInt = 640, height: SupportsInt = 360, selected_object: PhysicalObject | None = None, **camera_config: Unpack[CameraConfig]) Image#

Renders a world to an RGB image array.

Parameters:
  • world (World) – the world to render.

  • walls_height (float) – the height of the world boundary in cm.

  • width (int) – the width of the image in pixels.

  • height (int) – the height of the image in pixels.

  • selected_object (PhysicalObject | None) – an optional object to select.

  • **camera_config (CameraConfig) – the camera configuration.

Returns:

An array of shape (height, width, 3) and type uint8.

Return type:

Image

run(steps: SupportsInt = 1, time_step: SupportsFloat = 0.03333333333333333, physics_oversampling: SupportsInt = 3, termination: Callable[[pyenki.World], bool] | None = None, callback: Callable[[pyenki.World], None] | None = None) None#

Run a simulation.

Parameters:
  • steps (int) – the number of steps.

  • time_step (float) – the time step.

  • physics_oversampling (int) – the number of times the physics is updated per step to get a more fine-grained physical simulation compared to the sensor-motor loop.

  • termination (Callable[[World], bool] | None) –

    an optional function that makes the simulation terminate when it returns True

    def termination(World: world) -> bool: ...
    

  • callback (Callable[[World], None] | None) – An additional callback executed at each simulation step.

run_in_viewer(fps: SupportsFloat = 30, time_step: SupportsFloat = 0, factor: SupportsFloat = 1, helpers: bool = True, walls_height: SupportsFloat = 10, duration: SupportsFloat = -1, **camera_config: Unpack[CameraConfig]) None#

Runs a simulation while displaying it in real-time in a viewer.

Parameters:
  • world (World) – the world to display and run.

  • fps (float) – The framerate of the viewer in frames per second.

  • time_step (float) – The simulation time step in seconds.

  • factor (bool) – The real-time factor. If larger than one, the simulation will run faster then real-time.

  • helpers (bool) – Whether to display the helpers widgets.

  • walls_height (float) – the height of the world boundary in cm.

  • duration (float) – duration of the simulation in simulated time. Negative values are interpreted as infinite duration.

  • **camera_config (CameraConfig) – the camera configuration.

save_image(path: str, /, walls_height: SupportsFloat = 10, width: SupportsInt = 640, height: SupportsInt = 360, selected_object: PhysicalObject | None = None, **camera_config: Unpack[CameraConfig]) None#

Renders a world to an image file.

Parameters:
  • world (World) – the world to render.

  • path (str) – the file path.

  • walls_height (float) – the height of the world boundary in cm.

  • width (int) – the width of the image in pixels.

  • height (int) – the height of the image in pixels.

  • selected_object (PhysicalObject | None) – an optional object to select.

  • **camera_config (CameraConfig) – the camera configuration.

step(time_step: SupportsFloat, physics_oversampling: SupportsInt = 1) None#

Simulate a timestep

Parameters:
  • time_step (float) – the update timestep in seconds, should be below 1 (typically .02-.1)

  • physics_oversampling (int) – the amount of time the physics is run per step, as usual collisions require a more precise simulation than the sensor-motor loop frequency