Your first MARLIN program¶
This page builds the smallest useful MARLIN program: one thruster controlled by the left stick.
The goal is not to build a good robot yet. The goal is to understand the shape of every MARLIN program.
Complete program¶
This is the whole file. Save it as src/main.py in a MARLIN project. The
extension runs that file, so there is nothing else to create and nothing to
select.
from marlin import Robot, Thruster
THRUSTER = "M1" # change thruster to your thruster port number
robot = Robot()
robot.configure(
sensors={},
effectors={THRUSTER: Thruster},
)
def autonomous(robot):
while robot.running:
pass
def driver(robot):
while robot.running:
power = robot.controller.joystick("ONE").value
robot.thruster(THRUSTER).set_duty(power)
robot.run(autonomous=autonomous, driver=driver)
1. Import MARLIN classes¶
Robot is the main object. Almost everything goes through it.
Thruster is a type token. You use it to tell MARLIN what kind of hardware is
plugged into a port.
2. Create the robot object¶
This creates your program's handle to MARLIN. It does not open USB directly. The VS Code extension owns the Controller USB connection.
3. Declare hardware¶
configure() tells MARLIN what hardware your robot has.
This example has:
- no sensors
- one thruster on effector port
M1.
THRUSTER is an ordinary variable holding the port name. Naming it once at the
top means you change one line when your thruster moves to a different port,
instead of hunting through the file for every "M1". Sensor ports are S1–S6
and effector ports are M1–M8.
Pass hardware classes such as Thruster, not constructed objects such as
Thruster("M1").
4. Write match behaviour¶
The autonomous function runs during the Autonomous Period. This example does
nothing there yet, but it still needs the while robot.running: loop around
it. MARLIN calls the function once, when the phase starts, so a function that
returns straight away hands control back immediately instead of staying in
charge for the phase; MARLIN says so in the console when that happens. Leave
the stub in place; you fill in the body when you write an auton routine.
Your loop does not need a wait at the end. Reading robot.running paces it to
fifty times a second on its own, matching the rate MARLIN sends commands to the
robot. Do not add a time.sleep() of your own. See
running.
The driver function runs during the Driver Controlled Period.
Inside it, while robot.running: keeps your code active until the phase ends.
When the phase ends, robot.running becomes false and the loop exits.
robot.controller.joystick("ONE").value reads the latest cached stick position.
MARLIN does not stop and wait for a new controller packet.
"ONE" names one axis of one stick: the left stick's up and down direction.
The controller has four axes in total, named "ONE" to "FOUR"; see
Controller input for the diagram.
.value is a number from -100 to 100. set_duty() takes a number from -100 to
100. The ranges match on purpose, so power can be passed straight through
without conversion.
robot.thruster(THRUSTER).set_duty(power) updates the command for the thruster
on port M1. set_duty() returns nothing; you call it for its effect on the
robot.
5. Start the match¶
run() waits for the match, calls your callbacks for each phase, idles
outputs when callbacks finish, and shuts the robot down safely when the match
ends.
This ordering is a safety step, not a formality: run() only starts after
configure() has already succeeded, so the robot never accepts commands
against a hardware layout you did not declare.
What to remember¶
- Create one
Robot. - Call
configure()once beforerun(). - Put repeated behaviour inside
while robot.running:. - Read controller and sensor state from the
Robot. - Command hardware through accessors like
robot.thruster("M1"). - Do not open serial ports from your Python code.
Run it¶
This file does nothing until the extension runs it. Save it as src/main.py in
a MARLIN project, then follow Run your program.
You should see: pushing the left stick forward spins the thruster, pulling it back reverses it, and centring the stick stops it.
Where to go next¶
Get this running before you go further. Everything after this assumes you can put code on the robot and watch it move.
Then build the Complete robot program. It starts from the file on this page and grows it one step at a time into two thrusters, a servo, an IMU, and both match phases.
For the concepts behind the shape you just wrote, read Program structure.