Embodied simulators

Warning

qrobot_simulator is experimental. Its public interfaces and configuration may change between minor releases while common simulator contracts are defined.

The simulator extension contains two examples: the stationary grasping_robot and the mobile bug_world. Both separate physical world state, a self-contained Redis-connected robot, and persistent Matplotlib presentation.

The examples require the simulator extra and a Redis server on localhost:6379. Run them from a repository checkout with Poetry:

poetry run python examples/bug_world.py
poetry run python examples/grasping_robot.py

Grasping robot

The grasping simulation follows a ball approaching a stationary robot. Its distance and touch readings pass through independently timed qUnits, and the resulting actuator signal closes the gripper. The public example is composed from the world, the complete Redis-connected robot, and the live view below.

Live grasping simulation with an approaching blue ball and stationary robot
class qrobot_simulator.grasping_robot.GraspingWorld(arena: GraspingArena, robot: GraspingRobot, ball: BallPrey, elapsed: float = 0.0, touch_pressed: bool = False, readings: dict[str, float]=<factory>, correct_grips: int = 0, missed_grips: int = 0, empty_grips: int = 0, _inside_visit: bool = False, _visit_gripped: bool = False, _caught_at: float | None = None, _rng: Random = <factory>)[source]

Represent one stationary gripper and one wandering ball prey.

Parameters:
  • arena – Visible checkerboard dimensions.

  • robot – Physical gripper body controlled by an actuator.

  • ball – Ball prey moving in front of the gripper.

  • elapsed – Simulated time in seconds.

  • touch_pressed – Whether caught prey presses the touch sensor.

  • readings – Latest normalized proximity and touch readings.

  • correct_grips – Closing transitions that caught prey.

  • missed_grips – Grippable visits that ended uncaught.

  • empty_grips – Closing transitions made without grippable prey.

classmethod demo(robot: GraspingRobot | None = None, seed: int | None = None) GraspingWorld[source]

Create the configured arena, robot, and randomly placed ball prey.

Parameters:
  • robot – Existing robot to place in the world. A brainless robot is created when omitted.

  • seed – Optional seed for reproducible prey movement.

Returns:

Initialized world with its first sensor snapshot.

sensor_readings() dict[str, float][source]

Calculate the two normalized robot sensor values.

Returns:

Proximity and touch readings keyed by sensor name.

step(gripper_activation: float, dt: float) None[source]

Advance the encounter and apply the latest actuator output.

Parameters:
  • gripper_activation – Normalized command applied to the jaws.

  • dt – Positive interval in simulated seconds.

Raises:

ValueError – If dt is not positive.

class qrobot_simulator.grasping_robot.GraspingRobot(redis_config: RedisConfig | None = None, speed: float = 1.0, *, connect_brain: bool = True)[source]

Represent the stationary gripper body and its optional qBrain.

actuator_value() float[source]

Return the latest actuator output.

Returns:

Current activation, or zero before publication.

apply_activation(activation: float) None[source]

Map a normalized actuator value to the binary gripper state.

Parameters:

activation – Latest actuator output.

property brain_units: tuple[SensorialUnit | QUnit | ActuatorUnit, ...]

Return every qBrain worker in startup order.

Returns:

Sensors, qUnits, and the actuator when connected.

perceive(readings: dict[str, float]) None[source]

Copy normalized proximity and touch readings to the sensor units.

Parameters:

readings – Values keyed by configured sensor name.

Raises:

KeyError – If a reading names a sensor not present in the qBrain.

signals() GraspingSignals[source]

Read the latest perceptual and actuator outputs.

Returns:

Current qBrain outputs, including unpublished None values.

start_brain() None[source]

Start all independently scheduled qBrain workers.

stop_brain() None[source]

Stop workers and remove their Redis keys.

class qrobot_simulator.grasping_robot.GraspingWorldLiveView(arena: GraspingArena, interactive: bool = True)[source]

Display a persistent view of the gripper encounter and qBrain state.

close() None[source]

Close the Matplotlib figure owned by this view.

property is_open: bool

Return whether the Matplotlib figure still exists.

Returns:

True while the view’s figure remains open.

save(path: Path) Path[source]

Save the current frame to an image.

Parent directories are created when needed.

Parameters:

path – Destination image path.

Returns:

Destination path after the figure is saved.

update(world: GraspingWorld, signals: GraspingSignals | None = None, phase: str = 'RUNNING') None[source]

Refresh physical geometry and observable qBrain values.

Parameters:
  • world – Current simulation state to display.

  • signals – Latest observable qBrain outputs, when available.

  • phase – Short label describing the simulation phase.

Bug world

The bug simulation places the qBrain-controlled robot in a mobile ecosystem with blue prey and a red predator. Sensor readings and five behavioral actuators form a closed loop between the chessboard world and the complete bug robot; the internal prey and predator bodies remain implementation details of the world.

Live bug-world simulation with the qBrain robot, blue prey, and red predator
class qrobot_simulator.bug_world.BugWorld(board: ~qrobot_simulator.bug_world.world.bug_world.Chessboard, bug: ~qrobot_simulator.bug_world.robots.bug_robot.BugRobot, prey: list[~qrobot_simulator.bug_world.robots.blue_prey.BluePrey], predator: ~qrobot_simulator.bug_world.robots.red_predator.RedPredator, elapsed: float = 0.0, readings: dict[str, float] = <factory>, bitten_prey: int = 0, predator_bites: int = 0, bug_biting: bool = False, predator_biting: bool = False)[source]

Represent the bug, prey, predator, arena, sensors, and scores.

Parameters:
  • board – Checkerboard containing every robot.

  • bug – qBrain-controlled bug body.

  • prey – Blue prey population.

  • predator – Red predator pursuing the bug.

  • elapsed – Total simulated time in seconds.

  • readings – Latest bug sensor snapshot.

  • bitten_prey – Number of prey bitten by the bug.

  • predator_bites – Number of predator contacts scored against the bug.

  • bug_biting – Whether the bug bite indicator is visible.

  • predator_biting – Whether the predator bite indicator is visible.

classmethod demo(bug: BugRobot | None = None) BugWorld[source]

Create the configured demonstration ecosystem.

Parameters:

bug – Existing bug to place in the world. A brainless body is created when omitted.

Returns:

Initialized world with its first sensor snapshot.

property robots: tuple[Robot, ...]

Return all bodies in stable rendering order.

Returns:

Bug, prey, and predator bodies.

sensor_readings() dict[str, float][source]

Calculate the bug’s proximity and stereo RGB sensor values.

Returns:

Normalized readings keyed by configured sensor name.

step(activations: dict[str, float], dt: float) None[source]

Advance motion, interactions, and sensing by one interval.

Parameters:
  • activations – Current actuator values for the bug.

  • dt – Positive simulation interval in seconds.

Raises:

ValueError – If dt is not positive.

class qrobot_simulator.bug_world.BugRobot(redis_config: RedisConfig | None = None, *, connect_brain: bool = True)[source]

Represent the actuator-driven bug body and its qBrain units.

actuator_values() dict[str, float][source]

Read the current activation of every actuator.

Returns:

Activations keyed by actuator name; unavailable values become zero.

property brain_units: tuple[SensorialUnit | QUnit | ActuatorUnit, ...]

Return all independently scheduled qBrain units in startup order.

Returns:

Sensors, qUnits, and actuators in lifecycle order.

perceive(readings: dict[str, float]) None[source]

Copy world readings into the corresponding sensor interfaces.

Parameters:

readings – Normalized readings keyed by configured sensor name.

Raises:

KeyError – If a reading names a sensor not present in the qBrain.

qunint_values() dict[str, float][source]

Read the latest burts of every qunit.

Returns:

Bursts keyed by qunit name; unavailable values become zero.

start_brain() None[source]

Start all sensor, perceptual, cognitive, and actuator workers.

step(activations: dict[str, float], dt: float, bounds: tuple[float, float]) None[source]

Interpret actuator values and advance the body.

Parameters:
  • activations – Current values keyed by configured actuator name.

  • dt – Simulation interval in seconds.

  • bounds – Arena (width, height) in world units.

stop_brain() None[source]

Stop all workers and delete their Redis keys.

class qrobot_simulator.bug_world.BugWorldLiveView(board: Chessboard, interactive: bool = True)[source]

Display a persistent view of the world, sensors, and scores.

close() None[source]

Close the Matplotlib figure owned by this view.

property is_open: bool

Return whether the Matplotlib figure still exists.

Returns:

True while the view’s figure remains open.

save(path: Path) Path[source]

Save the current frame to an image.

Parent directories are created when needed.

Parameters:

path – Destination image path.

Returns:

Destination path after the figure is saved.

update(world: BugWorld) None[source]

Refresh all graphics and labels from a world snapshot.

Parameters:

world – Current simulation state to display.