Source code for genericroboticarm.robo_APIs.precise_flex.pf_simulation

"""
Simulation for PF400
"""
import time
from math import dist
from datetime import datetime


[docs] class PFSimulation: # mirror the gripper positions of the real implementation so simulated joint reads # (wherej/DestJ, axis 5) behave like the hardware GRIPPER_CLOSED = 74 GRIPPER_OPEN = 85 def __init__(self, simulated_plate: bool = False): # cartesian position, returned by wherec/DestC self.pos = [0, 0, 0, 0, 0, 0] # joint position, returned by wherej/DestJ. Axis 5 (index 4) is the gripper. self.joints = [0.0, 0.0, 0.0, 0.0, float(self.GRIPPER_OPEN), 0.0] # last commanded joint destination (what DestJ 1 reports) self.joint_dest = list(self.joints) # when True, the gripper cannot fully close, as if it were holding a plate self.simulated_plate = simulated_plate
[docs] def send_command(self, cmd: str) -> tuple[int, str]: """Mimics PFSocket.send_command: returns (error_code, answer).""" if "where" not in cmd and "Dest" not in cmd: print(f"{datetime.now()}: Simulate command {cmd}") parts = cmd.split() keyword = parts[0] if parts else "" if keyword in ("wherec", "DestC"): return 0, " ".join(str(v) for v in self.pos) if keyword == "wherej": return 0, " ".join(str(v) for v in self.joints) if keyword == "DestJ": # "DestJ 1" returns the target of the previous move; a bare "DestJ" returns # the current position while the robot is idle (see the TCS command reference) reads_target = len(parts) > 1 and parts[1] == "1" state = self.joint_dest if reads_target else self.joints return 0, " ".join(str(v) for v in state) if keyword == "MoveOneAxis": # MoveOneAxis <axis> <target> <profile> axis = int(parts[1]) - 1 target = float(parts[2]) self.joint_dest[axis] = target if axis == 4 and self.simulated_plate and target <= self.GRIPPER_CLOSED: # a held plate blocks the gripper from closing fully; the resulting gap # must stay above the detection threshold in currently_gripping_plate self.joints[axis] = self.GRIPPER_CLOSED + 3 else: self.joints[axis] = target time.sleep(.2) return 0, "" if keyword == "MoveJ": targets = [float(v) for v in parts[2:]] for index, target in enumerate(targets): self.joint_dest[index] = target self.joints[index] = target time.sleep(.5) return 0, "" if keyword == "MoveC": time.sleep(1.5) target = [float(coord) for coord in parts[2:]] d = dist(self.pos, target) time.sleep(d / 50) self.pos = target return 0, "" if keyword == "Speed": print(f"{datetime.now()}: Setting Speed to {parts[-1]}") return 0, "" return 0, "OK"