bb_so101's generated application.ex reads the SIMULATE environment
variable on boot. When it's set to any non-empty value, the robot boots in
:kinematic simulation mode — no Feetech controller, no serial port, no
hardware required.
Start the server in simulation mode
SIMULATE=1 mix phx.server
The dashboard at http://localhost:4000 behaves exactly as it does with real hardware, with two differences:
BB.Sim.ActuatorreplacesBB.Servo.Feetech.Actuator. It publishes aBeginMotionmessage with timing computed from the joint's velocity limit, so the 3D view animates as the simulated arm "moves".- The Feetech controller is omitted from the supervision tree. Anything that inspects controllers (e.g. parameter bridges over the bus) will report it as absent.
The safety system is still enforced: you must arm the robot before any command is allowed to mutate joint state.
How it works
The generated application.ex looks like this:
defp robot_opts do
if System.get_env("SIMULATE") do
[simulation: :kinematic]
else
[params: [config: [feetech: [device: "/dev/ttyUSB0"]]]]
end
endWhen SIMULATE is set, the robot is started with simulation: :kinematic.
BB's supervisor reads that option and:
- Omits any controller with
simulation: :omitset (which the Feetech controller does in the generated robot). - Replaces each actuator's module with
BB.Sim.Actuator.
Everything else — kinematic chain, command system, parameters, PubSub topics — runs unchanged.
Mixing simulation and real hardware
There's no built-in option to simulate some joints and drive others on real hardware. If you need that, define a second robot module with the joints you want to simulate (omit the actuators) and supervise both — Beam Bots is happy to run multiple robots in one BEAM.
IEx, tests, and CI
You can drop SIMULATE=1 on any command that boots the application:
SIMULATE=1 iex -S mix # interactive shell with the simulated arm
SIMULATE=1 mix run script.exs # one-off scripts against simulation
For tests and CI, the SIMULATE switch is usually unnecessary — tests that
need a running robot tend to start it explicitly with whatever opts they want
rather than relying on the application's child spec.
When simulation is enough
Use simulation for:
- Exercising command/state-machine logic before the arm is wired up
- Visual checks of the kinematic chain (link lengths, joint axes)
- Iterating on dashboard layouts and components
- Running CI without specialised hardware
When you do have hardware, switch back by dropping the env var — the same project boots against the real arm without any code changes.