Machine tending (bt.tending)¶
The machine's side of a tending handshake, authored as a program of its own — FANUC Robot Interface 2 signalling, or a machine with no interface worked through its panel. See Machine tending.
vmc = bt.parts.machine_tool(scene, "vmc", door="servo")
hs = bt.tending.fanuc_ri2(scene, vmc, cycle_s=42.0)
tl = scene.simulate_sequences(["tend", hs.program])
tending
¶
Machine tending: the machine's side of the handshake, authored as a program of its own (design/design-machine-tending.md §4).
A machine tool is not a device the robot commands — it runs a part
program and talks to the cell in a fixed vocabulary of signals. FANUC's
Robot Interface 2 says it in M-codes and I/O: M62 announces the end of
the cycle a few seconds early, M60 unclamps and opens the side door,
SERVICE REQUEST holds while the door is at its open end, the robot asks
for the work clamp and reports the exchange done, and the door closes
before the next cycle starts. Written out, that is one more PLC program
scanned beside the robot's — which is what these templates author:
vmc = bt.parts.machine_tool(scene, "vmc", door="servo")
hs = bt.tending.fanuc_ri2(scene, vmc, cycle_s=42.0)
tend = scene.sequence("tend") # the robot's program, by hand
tend.step("wait", transition=bt.seq.signal(hs.signal("notice")))
...
tl = scene.simulate_sequences(["tend", hs.program])
The templates put nothing in the scene but signals, a sequence and (by
default) the CNC as an I/O node hosting it — so the derived I/O list
shows the handshake as wires between two controllers, PLCopen export
carries the machine's POU on a resource of its own, and the interlock
table (scene.interlocks()) reads the guards below as rows. The door
enforces itself: a leaf the machine closes on an arm still inside stops
the bake at that tick, by name.
Three guards every template writes into the machine's program, the way ISO 16090-1 has a machining centre written:
- the side door opens only with the front door closed (the two are never open together — while the side door is open, the machine body is the fence);
- a cycle starts only with the side door at its closed end — the confirmation signal, not the command;
- nothing starts while the E-stop is pressed.
Four vocabularies: fanuc_ri2 (FANUC Robot Interface 2), haas_autodoor
(Haas M80/M81 auto door with a cell-safe input), generic (a
vendor-neutral request/acknowledge, its signal names yours to set) and
manual (no interface — the robot works the door and the panel).
FANUC_RI2
module-attribute
¶
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
GENERIC
module-attribute
¶
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
HAAS_AUTODOOR
module-attribute
¶
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
MANUAL
module-attribute
¶
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
Handshake
¶
What a template authored: the machine program's name, the door axis
it drives (or None), the I/O node it lives on, and the signals by
role — signal("service_req") is the name the robot's program waits
on, whatever the machine is called.
mtconnect_items
¶
The machine's lanes as MTConnect data items, for
bt.trace.read_mtconnect / to_mtconnect: Execution is
running, DoorState the side door's two lanes, EmergencyStop
the E-stop, ChuckState the work clamp (the nearest standard type
a vise clamp reports as). Only the roles this machine has.
MachineTool
¶
Bases: botrail.parts.Built
What machine_tool built, plus the names a tending program
addresses: the side door's axis (door, None for a manual door or
none), what rides on that door (door_objects — the leaf and its
trim, for a robot that slides it by hand), its end-of-travel lanes
(door_lanes = closed, open — the axis's stop lanes, or two zone
sensors on a loose leaf), the stroke and the world direction it opens
along (door_travel, door_axis), the front door's closed switch and
the E-stop lane the machine's program is guarded by (front_door_lane,
estop), the operator panel's Built and the button sensors on it.
door_axis
class-attribute
¶
Built-in immutable sequence.
If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.
If the argument is a tuple, the return value is the same object.
door_travel
class-attribute
¶
Convert a string or number to a floating-point number, if possible.
fanuc_ri2
¶
fanuc_ri2(
scene,
machine: MachineTool,
*,
cycle_s: float = 42.0,
clamp_s: float = 0.8,
notice_s: float = 5.0,
program: Optional[str] = None,
node: bool = True,
) -> Handshake
The FANUC Robot Interface 2 cycle, as the machine runs it.
Signals (all under <machine>/): running (a cycle is in progress),
notice (M62 — complete notice, notice_s before the end),
service_req (SERVICE REQUEST: the door is at its open end and the
machine waits for the robot), clamp (the work clamp, SO25_2),
and two the robot's program writes — clamp_req (asks for the
clamp once the blank is in the jaws) and service_ok (the exchange
is done and the arm is out).
The program <machine> (or program=): machining for
cycle_s - notice_s, the notice, then unclamp (clamp_s), the side
door to its open end, SERVICE REQUEST until the robot asks for the
clamp, the clamp (clamp_s), then wait for service_ok, close the
door and start the next cycle. A machine without an automatic door
(door="manual" or none) skips the door steps — the interlock is
then the robot's, or nobody's.
The one thing to get right on the robot's side: service_ok goes up
after the arm has left the enclosure. Set it earlier and the door
closes on the arm — which the bake refuses at that instant, naming
the door, the leaf, the robot and the link (DeviceCollision).
generic
¶
generic(
scene,
machine: MachineTool,
*,
cycle_s: float = 42.0,
clamp_s: float = 0.8,
signals: Optional[dict[str, str]] = None,
program: Optional[str] = None,
node: bool = True,
) -> Handshake
A vendor-neutral request/acknowledge handshake — the shape most integrators wire when the machine's interface is a handful of relays:
- the machine says
runningwhile a cycle runs andreadyonce the part is unclamped and the door (if driven) stands open; - the cell asks
clamp_reqwith the blank in the jaws and getsclampback, then reportsexchange_doneonce the arm is out; - the machine closes the door and starts the next cycle.
signals renames any role to the maker's tag ({"ready": "vmc/M_FIN",
...}) — a catalog pack's interface.signals slots in here — so the
I/O list and the handshake spec carry the names the electrician reads.
A machine without a driven door skips the door steps. Guards: the
door opens only with the front door closed; the next cycle starts only
with the side door confirmed closed and no E-stop.
haas_autodoor
¶
haas_autodoor(
scene,
machine: MachineTool,
*,
cycle_s: float = 42.0,
clamp_s: float = 0.8,
program: Optional[str] = None,
node: bool = True,
) -> Handshake
The Haas auto-door cycle: M80 opens the door, M81 closes it, and
the door works only while the cell-safe input is on (a light
curtain clear, a cell fence shut); cycle start closes the door.
Signals (under <machine>/): running, part_done (the program has
ended and the part is unclamped — the M-code relay a robot cell wires
to), clamp (a user M-code relay, M21-style, with its M-Fin), and
three the cell writes — cell_safe (it is safe to move the
door), clamp_req (clamp the blank) and start_req (remote cycle
start, once the arm is out). A driven side door is required
(door="air" / "servo"): M80/M81 are auto-door codes.
The program: machining for cycle_s, unclamp (clamp_s) and raise
part_done, wait for cell_safe and the front door closed, open
the door, clamp on request, wait for start_req with no E-stop,
close the door, and start once it reads closed.
manual
¶
manual(
scene,
machine: MachineTool,
*,
cycle_s: float = 42.0,
clamp_s: float = 0.8,
buttons: Sequence[str] = (
"unclamp",
"clamp",
"cycle_start",
),
program: Optional[str] = None,
node: bool = True,
) -> Handshake
A machine with no robot interface, worked through its panel — the retrofit case: the robot pulls the door and presses the buttons an operator would.
buttons names the panel buttons for unclamp, clamp and cycle start,
in that order (they must exist on the machine's panel). Signals:
running and clamp, plus the buttons' own zone lanes. The program
<machine>: machining for cycle_s, then wait for UNCLAMP, release
the clamp (clamp_s), wait for CLAMP, clamp (clamp_s), then wait
for CYCLE START with the side door at its closed end — a start
pressed with the door open is ignored, the way a guard interlock
ignores it (ISO 16090-1), and the bake reports the deadlock naming
this step.