Skip to content

CoppeliaSim: Distributed Control Architecture and Scripting API for Multi-Robot Simulation

By Jeff 6 views
CoppeliaSim distributed control architecture showing per-object embedded scripts for Robot A, Robot B, and external Python client
CoppeliaSim distributed control architecture showing per-object embedded scripts for Robot A, Robot B, and external Python client

CoppeliaSim (formerly V-REP) is a versatile, cross-platform robot simulator developed by Coppelia Robotics that distinguishes itself through a unique distributed control architecture — every object in the scene can carry its own embedded script, enabling fine-grained, modular simulation logic without a monolithic controller. This article examines CoppeliaSim's scripting model, its Lua and Python remote API, and best practices for building scalable multi-robot simulations.


Distributed Control: The Core Paradigm

Unlike simulators that rely on a single external controller, CoppeliaSim embeds scripts directly into scene objects. There are four script types:

Script Type Scope Typical Use
Main Script Entire simulation Simulation loop orchestration
Child Script Single scene object Per-robot or per-sensor logic
Customization Script Object (non-threaded) UI callbacks, property editors
Add-on Script Global (persistent) Plugin-like background services

Child scripts run either threaded (blocking, sequential logic) or non-threaded (called every simulation step). For most robot controllers, threaded child scripts are preferred because they allow sim.wait() calls and natural state-machine coding patterns.

-- Threaded child script example: simple P-controller for a joint
function sysCall_threadmain()
    local jointHandle = sim.getObject('/Robot/Joint1')
    local targetPos = math.pi / 4  -- 45 degrees
    while true do
        local currentPos = sim.getJointPosition(jointHandle)
        local error = targetPos - currentPos
        sim.setJointTargetVelocity(jointHandle, error * 2.0)
        sim.switchThread()  -- yield to simulation step
    end
end

This per-object scripting model makes it straightforward to clone a robot model and have each instance run its own independent controller — a significant advantage for swarm and multi-robot scenarios.


Remote API: Python and External Control

ZeroMQ Remote API stepped simulation workflow between Python client and CoppeliaSim engine

For teams preferring Python or integrating with external frameworks (ROS, ML pipelines), CoppeliaSim exposes a Remote API (legacy B0-based) and the newer ZeroMQ Remote API introduced in CoppeliaSim 4.3+.

ZeroMQ Remote API (Recommended)

The ZMQ API provides a synchronous, request-reply interface over a ZeroMQ socket. It eliminates the polling overhead of the legacy API and supports both blocking and non-blocking calls.

from coppeliasim_zmqremoteapi_client import RemoteAPIClient

client = RemoteAPIClient()
sim = client.require('sim')

sim.startSimulation()

robot_base = sim.getObject('/MobileRobot')
left_motor = sim.getObject('/MobileRobot/LeftMotor')
right_motor = sim.getObject('/MobileRobot/RightMotor')

# Drive forward at 1.5 rad/s for 3 seconds
sim.setJointTargetVelocity(left_motor, 1.5)
sim.setJointTargetVelocity(right_motor, 1.5)
sim.step()  # advance one simulation step

import time
time.sleep(3)

sim.stopSimulation()

Install the client library with:

pip install coppeliasim-zmqremoteapi-client

The ZMQ API supports stepped simulation — the external client controls when each simulation step advances — which is essential for deterministic reinforcement learning training loops.


Sensor Simulation and Data Retrieval

CoppeliaSim provides built-in models for:

  • Proximity sensors (ultrasonic, infrared) — configurable detection volumes
  • Vision sensors — RGB, depth, and segmentation outputs
  • Force/torque sensors — 6-axis wrench measurement
  • IMUs — via the simIMU plugin

Retrieving vision sensor data in Python:

vision_sensor = sim.getObject('/Robot/VisionSensor')
sim.handleVisionSensor(vision_sensor)

img, resolution = sim.getVisionSensorImg(vision_sensor)
# img is a flat list of RGB bytes; reshape for OpenCV:
import numpy as np, cv2
frame = np.array(img, dtype=np.uint8).reshape(resolution[1], resolution[0], 3)
frame = cv2.flip(frame, 0)  # CoppeliaSim uses bottom-left origin

For depth data, set the sensor to depth map mode and call sim.getVisionSensorDepth() — the returned buffer maps directly to a NumPy float32 array suitable for point-cloud generation.


Multi-Robot Simulation Best Practices

1. Use Model Files (.ttm) for Reusable Robots

Save each robot as a .ttm (scene model) file. Load instances programmatically:

robot_handle = sim.loadModel('/path/to/mobile_robot.ttm')
sim.setObjectPosition(robot_handle, -1, [x, y, 0.1])

This pattern supports spawning dozens of robot instances without manual scene editing.

2. Leverage Simulation Time, Not Wall-Clock Time

Always use sim.getSimulationTime() for timing logic inside scripts. CoppeliaSim can run faster-than-real-time (up to 10× in headless mode), so wall-clock time.sleep() calls will desynchronize with the simulation.

3. Headless Mode for Batch Experiments

Launch CoppeliaSim without a GUI for CI pipelines or parameter sweeps:

coppeliaSim -h -s5000 -q /path/to/scene.ttt

Flags: -h (headless), -s5000 (stop after 5000 ms sim time), -q (quit on stop).

4. ROS 2 Integration via simROS2 Plugin

The simROS2 plugin bridges CoppeliaSim topics and services to ROS 2. Enable it in userconfigFile.txt and use sim.ros2.createPublisher() / sim.ros2.createSubscription() from within child scripts to publish sensor data and receive velocity commands — no external bridge node required.


Performance Considerations

CoppeliaSim multi-robot simulation performance: speed vs robot count and per-step time breakdown

Scenario Recommended Setting
Many rigid bodies Enable Bullet 2.83 engine; reduce convex hull resolution
Soft-body / cloth Switch to Vortex or Newton engine
Real-time hardware-in-the-loop Enable real-time simulation mode; pin to a single CPU core
RL training (fast rollouts) Headless + ZMQ stepped mode; disable rendering

CoppeliaSim's physics engine is selectable per-scene (ODE, Bullet, Vortex, Newton, MuJoCo via plugin), allowing engineers to match the solver to the physical phenomena being modeled.


Comparison with Peer Simulators

Radar chart comparing CoppeliaSim physics engines: Bullet, ODE, Vortex, and MuJoCo across five criteria

Feature CoppeliaSim Gazebo (Classic) Webots
Embedded scripting ✅ Per-object ❌ External plugins ✅ Per-robot
Python remote API ✅ ZMQ ✅ (via ROS)
Physics engine choice ✅ 5 engines ✅ 3 engines ✅ ODE
Built-in robot library ✅ 200+ models
License Free (Edu) / Commercial Apache 2.0 Apache 2.0

Getting Started

CoppeliaSim's distributed scripting model and flexible remote API make it a compelling choice for teams building multi-robot systems, swarm experiments, or reinforcement learning environments where per-agent control granularity and simulation speed are paramount.

Tags: CoppeliaSim V-REP multi-robot simulation ZeroMQ Remote API robot scripting