Control a robot with Python
A controller is a small program that tells the robot how to move. This guide starts with ordinary Python. The app prepares the full ROS environment when you need ROS commands or ROS libraries.
Choose where your simulation runs
- Installed app — recommended for your first project: the robot runs on your computer. Follow the installed-app steps below.
- Website: the robot runs on the server. Follow the website steps below. You need Python, but you do not need to install ROS.
Use a personal workspace. Public LIVE is a shared demonstration that you can watch.
Website rendering uses lower graphics quality than the installed app. Only a limited number of users can run server simulations at once. If all slots are busy, join the queue or practise locally.
Installed app: start a WAM-V world
- Install WWW-POSIM and VS Code.
- Open WWW-POSIM. Sign in with your verified email account and select Start simulator. On Windows/Linux, start Docker first.
- In the browser's Workspace window, keep the default Busan coordinates and generate the map.
- Choose WAM-V. In its control-mode menu, choose ROS 2 direct control.
- Select Start world. Wait until the robot appears and the world is running. Keep the app and browser open.
The app runs the simulator. VS Code is the editor where you write and run your Python program.
Installed app: open your project in VS Code
- In the WWW-POSIM app, select Create Python project.
- Create an empty folder called
posim-controllerin Documents and select it. The app writes example programs and editor settings there. - Open VS Code. Select File → Open Folder and choose
posim-controller. If prompted, trust the folder you just created. - Open Extensions in VS Code and install Microsoft's Python and Python Debugger extensions.
- Windows/Linux: also install Microsoft's Dev Containers extension. Press Ctrl+Shift+P, choose Dev Containers: Reopen in Container, and wait for setup. You should see a container name in the lower-left corner.
- Mac: press Cmd+Shift+P, choose Python: Select Interpreter, then choose the bundled Python path shown in the project's README. The project supplies its ROS environment settings.
- Select Terminal → New Terminal. A terminal is a text box where you type commands. Paste this line and press Enter:
python controller.py
You should see the robot's x, y and z coordinates. Numbers mean that your program received a fresh position from the simulator.
On Mac, the selected interpreter is the app's bundled Python. On Windows/Linux, VS Code and Python run inside the prepared container. You can also choose Open ROS terminal in the app, select your project folder and run the same command there.
Move forward for two seconds
Open controller.py in VS Code. Replace its contents with the code below, then save the file.
from www_posim_ros import Session
with Session.local(control=True) as sim:
topic = next(name for name, kind in sim.topics.items()
if kind == "nav_msgs/msg/Odometry")
print("Before:", sim.latest(topic)["pose"]["pose"]["position"])
sim.set_velocity(forward=0.3, yaw_rate=0.0, duration=2.0)
print("After:", sim.latest(topic)["pose"]["pose"]["position"])
Run it in the VS Code terminal:
python controller.py
Watch WAM-V in the browser. The program asks for 0.3 metres per second forward motion for two seconds, then stops sending thrust commands. The robot may still drift because of inertia or waves. The printed positions need not differ by an exact distance.
To turn left, change yaw_rate=0.0 to yaw_rate=0.1. Positive yaw means a left turn. Use the browser's Stop button if you want to stop control immediately.
Website: prepare Python and VS Code
Use this path when you want the simulation to run on the website.
- Open www-posim.vercel.app, sign in and create your own WAM-V world in ROS 2 direct control mode. Wait for the running world.
- Install VS Code and its Microsoft Python extension.
- Follow only the block for your computer below. Copy one block into its terminal and press Enter. The
.venvfolder holds Python packages for this project.
Windows — PowerShell
Install the Python install manager. Open a new PowerShell window from the Start menu, then paste:
py install 3.14
mkdir "$HOME\posim-controller"
cd "$HOME\posim-controller"
py -3.14 -m venv .venv
.\.venv\Scripts\python.exe -m pip install https://github.com/IOES-Lab/homebrew-www-posim/releases/download/v0.5.4/www_posim_ros-0.4.0-py3-none-any.whl
Mac — Terminal
Install Python 3.14 using the macOS installer from Python.org. Open Applications → Utilities → Terminal, then paste:
mkdir -p ~/posim-controller
cd ~/posim-controller
python3.14 -m venv .venv
.venv/bin/python -m pip install https://github.com/IOES-Lab/homebrew-www-posim/releases/download/v0.5.4/www_posim_ros-0.4.0-py3-none-any.whl
Ubuntu — Terminal
Press Ctrl+Alt+T to open a terminal. Paste:
sudo apt update
sudo apt install -y python3-venv python3-pip
mkdir -p ~/posim-controller
cd ~/posim-controller
python3 -m venv .venv
.venv/bin/python -m pip install https://github.com/IOES-Lab/homebrew-www-posim/releases/download/v0.5.4/www_posim_ros-0.4.0-py3-none-any.whl
sudo may ask for your computer's password. Characters do not appear while you type it; press Enter after typing.
Website: run your program in VS Code
- In VS Code, select File → Open Folder and open
posim-controllerin your home folder. - Install Microsoft's Python extension if you have not already done so.
- Open the command palette with Ctrl+Shift+P on Windows/Linux or Cmd+Shift+P on Mac. Select Python: Select Interpreter and choose the project's
.venv. - Create a file named
controller.py. Paste the following code. ReplaceYOU@example.comwith your account email and save.
from www_posim_ros import Session
with Session.remote(email="YOU@example.com", control=True) as sim:
topic = next(name for name, kind in sim.topics.items()
if kind == "nav_msgs/msg/Odometry")
print(sim.latest(topic)["pose"]["pose"]["position"])
sim.set_velocity(forward=0.3, yaw_rate=0.0, duration=2.0)
- Select Terminal → New Terminal. Run the command for your computer:
Windows:
.\.venv\Scripts\python.exe controller.py
Mac/Ubuntu:
.venv/bin/python controller.py
- At
Password:, type your WWW-POSIM password and press Enter. Characters do not appear while you type. Watch WAM-V move in the website.
The program runs on your computer and sends commands to your own server workspace. Importing the package does not sign in or start a connection; entering the with block connects.
If something does not work
No module named www_posim_ros: select the project's Python interpreter. For a website project, repeat the package-install command with that.venvPython.- No fresh telemetry: check that your world is running and the robot has appeared. A topic name alone does not mean data is arriving.
- Start your own workspace in ROS 2 direct-control mode: create a world with that control mode selected.
controller_busy: stop the other program controlling this world, then run your program again.- World or robot changed: stop the program and start it again to obtain the current connection profile.
- Installed ROS tools fail: check
~/.www-posim-ros/domain-76/client.loginside the prepared environment. Stop and reopen the ROS tools if needed.
Advanced: full ROS, sensors and control details
Use ROS commands
Choose Open ROS terminal in the installed app and select your project folder. The terminal prints ROS connected. Telemetry and topic echo are ready. The prepared terminals share a local relay that makes the simulator's sensor data available to ROS programs.
ros2 topic list
ros2 topic echo /model/wamv/odometry --once --field pose.pose.position
ros2 topic echo /model/wamv/imu --once
For a full ROS program, use the generated ros_controller.py. It imports rclpy, the Python interface to ROS, and subscribes to odometry. ROS names a robot's position-and-motion message odometry.
python ros_controller.py
Press Ctrl+C to stop the program. Add your own dependencies in the prepared controller environment. RViz is an optional ROS visualization tool and must be installed in that environment if you want to use it.
Use the launcher CLI
On Ubuntu, the launcher command is www-posim. On Mac, use /Applications/WWW-POSIM.app/Contents/MacOS/WWW-POSIM in its place. On Windows, run the installed WWW-POSIM.exe by its full path in PowerShell using & before the path.
www-posim ros init ./posim-controller
www-posim ros shell --workspace ./posim-controller
www-posim ros run ./posim-controller/controller.py
www-posim ros stop
The run command prepares ROS and the shared relay before running the script. stop closes app-managed controllers. Closing the installed simulator also stops its prepared controllers. Close editor containers when you finish using them.
BlueROV thrusters
Use six thruster values in native joint order, in newtons. WAM-V uses two values, left and right. Begin with neutral input:
from www_posim_ros import Session
with Session.local(control=True) as sim:
sim.set_thrusters([0.0] * 6, duration=1.0)
- WAM-V velocity limits: forward ±1.5 m/s, yaw ±0.5 rad/s
- WAM-V thrust limits: ±200 N per motor
- BlueROV thrust limits: ±50 N per motor
- Helper duration: more than 0, up to 300 seconds
- Command watchdog: 0.75 seconds without a valid update
The helpers repeat commands at about 10 Hz and release control afterward. sim.stop() interrupts the current helper from another thread. Disconnection ends control; commands do not resume automatically after a network error. Neutral input does not remove inertia or waves.
Use an existing ROS installation with a web workspace
Use a compatible ROS 2 Lyrical environment with standard message packages. For Ubuntu 26.04, follow the official ROS installation steps. On Windows, an Ubuntu 26.04 WSL2 environment can host ROS; see Microsoft's WSL guide.
In the terminal where ROS is loaded:
python3 -m venv --system-site-packages .venv-ros
source .venv-ros/bin/activate
python -m pip install https://github.com/IOES-Lab/homebrew-www-posim/releases/download/v0.5.4/www_posim_ros-0.4.0-py3-none-any.whl
export ROS_DOMAIN_ID=76
export ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST
www-posim-connect --server https://www-posim.vercel.app/api --email YOU@example.com --control
Use a compatible virtual environment if your Python installation requires one. Keep this connector running while your ROS controller runs in another terminal with the same environment and ROS domain. Mac users can load the app environment with:
eval "$(/Applications/WWW-POSIM.app/Contents/MacOS/WWW-POSIM --ros-env)"
Messages and connection interfaces
Session.latest() returns ROS message fields as Python dictionaries. Binary image/point-cloud fields remain base64 strings when the bridge sends them that way. It waits for fresh telemetry; use timeout and max_age to set the wait and freshness limits.
/api: account login and current workspace profile/ros: read-only sensor subscriptions/control: exclusive, bounded commands for the current world- WAM-V ROS command:
geometry_msgs/msg/TwistStampedon/wwos/cmd_vel, body framebase_link - Thruster ROS command:
std_msgs/msg/Float64MultiArrayon/wwos/thrusters
The full relay converts sensor fields into standard ROS messages and derives a local robot-follow transform from received odometry. A custom robot may need its own message definitions, URDF or TF tree. Arbitrary services and pose writes are outside this control interface.
Topics appear but echo is empty
Open the app's ROS terminal and run the checks there. The connector, controller and ROS command terminal need the same ROS version, ROS_DOMAIN_ID and middleware (RMW_IMPLEMENTATION). After changing middleware, stop the ROS daemon and restart the connector and controller.
ros2 daemon stop
python3 -c "from rclpy.utilities import get_rmw_implementation_identifier; print(get_rmw_implementation_identifier())"
ros2 topic info /model/wamv/odometry --verbose
ros2 topic echo /model/wamv/odometry --once --qos-reliability best_effort
A reliable publisher can serve a best-effort subscriber. A best-effort publisher cannot serve a subscriber that requires reliable delivery. Check the offered and requested QoS before changing it.
For an existing Ubuntu/WSL ROS installation, you can try CycloneDDS. Run these commands in both the connector terminal and the controller terminal before starting them:
sudo apt install ros-lyrical-rmw-cyclonedds-cpp
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
ros2 daemon stop
The Mac native app uses CycloneDDS. The packaged Docker environment uses Fast DDS. The website connection carries messages over WebSocket; its server and your local relay have separate DDS domains. See the ROS middleware guide for advanced configuration.