Sequences (bt.seq)¶
The process vocabulary: a sequence is a list of steps, and a step is entry actions plus a transition condition, evaluated on a fixed scan cycle — the PLC step-advance model.
sq = scene.sequence("cycle")
sq.step("feed", actions=[bt.seq.start("belt")], transition=bt.seq.signal("eye"))
sq.step("stop", actions=[bt.seq.stop("belt")])
sq.step("pick", actions=[bt.seq.motion("approach"), bt.seq.attach("crate")])
Omitting transition supplies the obvious default: a step that starts a motion
waits for it (done()), a step that starts nothing falls through
(immediately()).
Actions at a glance¶
| Action | Effect |
|---|---|
motion(name) |
Start a named motion; await it with done() |
ramp(targets, duration) |
Drive joints to targets over a fixed duration — gripper open/close |
attach(obj) / detach(obj) |
Grasp, and release where the robot holds it |
track(obj) / untrack() |
Latch taught poses onto a moving part, and let go |
set_signal(name, value) |
Write an internal signal (declared with scene.define_signal) |
start(device) / stop(device) |
Run or halt a device — a conveyor or a source |
set_speed(device, speed) |
Rescale a conveyor's velocity, direction kept |
move_to(device, position) |
Command a linear axis; await with device_done |
Conditions at a glance¶
| Condition | Advances when |
|---|---|
immediately() |
Always, on the next scan |
done() |
This step's motion has finished |
robot_done(robot) |
A named robot is idle — the inter-robot handshake |
elapsed(seconds) |
A timer expires |
signal(name, value) |
A signal, sensor, or device state matches |
device_done(device) |
A device reached its commanded target |
all_of(...) / any_of(...) |
Composed conditions hold |
Reference¶
seq
¶
PLC-style sequence authoring: action / transition-condition helpers and
the step builder returned by scene.sequence(name).
A sequence is a list of steps (工程). Each step fires its entry actions
and completes when its transition condition holds — the SFC /
step-ladder mental model. When transition is omitted, a step that
starts a motion or ramp waits for it (done()); anything else moves on
immediately().
sq = scene.sequence("pick_place")
sq.step("approach", actions=[bt.seq.motion("approach")])
sq.step("close", actions=[bt.seq.ramp({"finger": 0.008}, 0.4)])
sq.step("grasp", actions=[bt.seq.attach("/World/Conveyor/Box_A")])
sq.step("carry", actions=[bt.seq.motion("to_pallet")])
sq.step("release", actions=[bt.seq.detach("/World/Conveyor/Box_A")])
timeline = sq.simulate()
SelectBuilder
¶
Arms of one branching step (see _Steps.select).
when
¶
when(condition: Dict[str, Any]) -> ArmBuilder
Appends an arm guarded by condition. Arms are tried in the
order added (SFC's left-to-right priority); the first whose
condition holds runs. An arm left empty skips straight to the
rejoin.
ArmBuilder
¶
Bases: botrail.seq._Steps
One arm's step list — the same step/select API as the
sequence itself, so arms nest.
SequenceBuilder
¶
Bases: botrail.seq._Steps
Accumulates steps for one sequence, mirroring every edit into the scene (and any connected studio). Creating a builder for an existing sequence name starts it over from zero steps.
simulate
¶
Rolls the sequence out (see Scene.simulate_sequence).
scenario runs it under a named initial-state delta
(scene.add_scenario).
toolpath
¶
Start a toolpath (continuous Cartesian process path — see
bt.toolpath): an automatic approach to the path start, then the
feed-floored follow. Await it with done(). robot names the
instance (required when the scene has several robots).
ramp
¶
ramp(
targets: Mapping[str, float],
duration: float,
robot: Optional[str] = None,
) -> Dict[str, Any]
Ramp joints to targets over duration s (gripper open/close);
await it with done(). robot names the instance (required when
the scene has several robots).
attach
¶
attach(
obj: str,
link: Optional[str] = None,
touch_links: Union[str, Iterable[str], NoneType] = None,
robot: Optional[str] = None,
) -> Dict[str, Any]
Grasp: rigidly attach an obstacle at its current relative pose.
robot names the carrying instance (required with several robots).
touch_links="tool" exempts the whole tool subtree — palm and
fingers — which a closed gripper needs (the default exempts only the
anchor link's own chain).
detach
¶
Release: the obstacle's pose freezes where the robot holds it.
track
¶
Conveyor tracking: latch onto a moving part. Until :func:untrack,
every commanded pose is carried by the part's motion since this step, so
poses taught at the station keep meeting the part while it travels — the
line never has to stop. Grasping the tracked part freezes the offset, so
the lift after it goes straight up. Planned motions cannot run while
tracking; ramps can.
untrack
¶
Stop following the tracked part; the robot holds where it stands.
set_signal
¶
Write an internal signal (declare it with scene.define_signal).
set_speed
¶
Rescale a conveyor's velocity to speed (m/s, direction kept).
move_to
¶
Command a linear axis to position (metres) — or a lift to a
named stop (move_to("lift", "2F")); await with device_done.
A lift's cargo (vehicles and loose parts in its capture zone) is
fixed the moment this fires: the doors are closed.
goto
¶
Dispatch a vehicle to a named station (the AGV call); await arrival
with device_done. Travel is uninterruptible: a second goto while
the vehicle is still moving is a sequencing error.
advance
¶
Indexed transfer: run a stopped conveyor for exactly distance
metres along its velocity direction, then stop; await it with
device_done. The final scan tick moves exactly the remainder, so
the pitch is exact no matter how the scan period divides it — no more
elapsed(pitch/v) plus one tick of slack.
robot_done
¶
The named robot has no motion/ramp in flight — whichever step started it. The idle test interlocks are built from.
signal
¶
Level test of a signal (internal relay or sensor input).
rising
¶
Rising edge (-|P|-): the signal turned on since this program's
previous scan — "the next part", not one already sitting on the
beam. Startup state is not an edge.
falling
¶
Falling edge (-|N|-): the signal turned off since this
program's previous scan.
device_done
¶
A linear axis has reached its commanded position.
otherwise
¶
Always-true branch guard — the else arm of a select. Put it
last: arms are tried in order, so it catches whatever the guards
before it did not (and the exported script skips the wait entirely,
since some arm is always ready).