From a73cb0b6e1ddf13be254fb9150fda74a8cb73e86 Mon Sep 17 00:00:00 2001 From: Gonzalo Casas Date: Wed, 27 Mar 2024 21:09:10 +0100 Subject: [PATCH] =?UTF-8?q?blacken=20=F0=9F=96=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/compas_rrc/__init__.py | 117 +++++++++++++++------------------- src/compas_rrc/__install.py | 4 +- src/compas_rrc/__version__.py | 27 +++++--- src/compas_rrc/client.py | 99 ++++++++++++++++++---------- src/compas_rrc/custom.py | 11 +++- src/compas_rrc/io.py | 36 +++++------ src/compas_rrc/motion.py | 72 ++++++++++++++------- src/compas_rrc/msg.py | 8 +-- src/compas_rrc/utility.py | 74 +++++++++++---------- src/compas_rrc/watch.py | 16 ++--- tests/ipy_test_runner.py | 6 +- tests/test_client.py | 2 +- tests/test_motion.py | 56 +++++++++++++--- 13 files changed, 319 insertions(+), 209 deletions(-) diff --git a/src/compas_rrc/__init__.py b/src/compas_rrc/__init__.py index 3f94b298..82506ea2 100644 --- a/src/compas_rrc/__init__.py +++ b/src/compas_rrc/__init__.py @@ -85,12 +85,9 @@ __copyright__, __license__, __url__, - __version__ -) -from compas_rrc.client import ( - AbbClient, - RosClient + __version__, ) +from compas_rrc.client import AbbClient, RosClient from compas_rrc.common import ( CLIENT_PROTOCOL_VERSION, ExecutionLevel, @@ -99,7 +96,7 @@ FutureResult, InstructionException, RobotJoints, - TimeoutException + TimeoutException, ) from compas_rrc.custom import CustomInstruction from compas_rrc.io import ( @@ -109,15 +106,9 @@ ReadGroup, SetAnalog, SetDigital, - SetGroup -) -from compas_rrc.motion import ( - Motion, - MoveToFrame, - MoveToJoints, - MoveToRobtarget, - Zone + SetGroup, ) +from compas_rrc.motion import Motion, MoveToFrame, MoveToJoints, MoveToRobtarget, Zone from compas_rrc.msg import PrintText from compas_rrc.utility import ( Debug, @@ -130,58 +121,54 @@ SetTool, SetWorkObject, Stop, - WaitTime -) -from compas_rrc.watch import ( - ReadWatch, - StartWatch, - StopWatch + WaitTime, ) +from compas_rrc.watch import ReadWatch, StartWatch, StopWatch -__all_plugins__ = ['compas_rrc.__install'] +__all_plugins__ = ["compas_rrc.__install"] __all__ = [ - '__url__', - '__version__', - '__author__', - '__author_email__', - '__license__', - '__copyright__', - 'CLIENT_PROTOCOL_VERSION', - 'FeedbackLevel', - 'ExecutionLevel', - 'InstructionException', - 'TimeoutException', - 'FutureResult', - 'ExternalAxes', - 'RobotJoints', - 'RosClient', - 'AbbClient', - 'SetDigital', - 'SetAnalog', - 'SetGroup', - 'PulseDigital', - 'ReadAnalog', - 'ReadDigital', - 'ReadGroup', - 'Zone', - 'Motion', - 'MoveToJoints', - 'MoveToFrame', - 'MoveToRobtarget', - 'PrintText', - 'CustomInstruction', - 'Noop', - 'GetFrame', - 'GetJoints', - 'GetRobtarget', - 'SetAcceleration', - 'SetTool', - 'SetMaxSpeed', - 'Stop', - 'WaitTime', - 'SetWorkObject', - 'Debug', - 'ReadWatch', - 'StartWatch', - 'StopWatch', + "__url__", + "__version__", + "__author__", + "__author_email__", + "__license__", + "__copyright__", + "CLIENT_PROTOCOL_VERSION", + "FeedbackLevel", + "ExecutionLevel", + "InstructionException", + "TimeoutException", + "FutureResult", + "ExternalAxes", + "RobotJoints", + "RosClient", + "AbbClient", + "SetDigital", + "SetAnalog", + "SetGroup", + "PulseDigital", + "ReadAnalog", + "ReadDigital", + "ReadGroup", + "Zone", + "Motion", + "MoveToJoints", + "MoveToFrame", + "MoveToRobtarget", + "PrintText", + "CustomInstruction", + "Noop", + "GetFrame", + "GetJoints", + "GetRobtarget", + "SetAcceleration", + "SetTool", + "SetMaxSpeed", + "Stop", + "WaitTime", + "SetWorkObject", + "Debug", + "ReadWatch", + "StartWatch", + "StopWatch", ] diff --git a/src/compas_rrc/__install.py b/src/compas_rrc/__install.py index 2c78ff5a..7f07eee5 100644 --- a/src/compas_rrc/__install.py +++ b/src/compas_rrc/__install.py @@ -1,6 +1,6 @@ import compas.plugins -@compas.plugins.plugin(category='install') +@compas.plugins.plugin(category="install") def installable_rhino_packages(): - return ['compas_rrc'] + return ["compas_rrc"] diff --git a/src/compas_rrc/__version__.py b/src/compas_rrc/__version__.py index bcc3a296..5d6f0699 100644 --- a/src/compas_rrc/__version__.py +++ b/src/compas_rrc/__version__.py @@ -1,10 +1,19 @@ -__title__ = 'compas_rrc' -__description__ = 'COMPAS RRC: Library for ABB Robots' -__url__ = 'https://github.com/compas-rrc/compas_rrc' -__version__ = '1.1.0' -__author__ = 'ETH Zurich' -__author_email__ = 'rrc@arch.ethz.ch' -__license__ = 'MIT license' -__copyright__ = 'Copyright 2019 ETH Zurich' +__title__ = "compas_rrc" +__description__ = "COMPAS RRC: Library for ABB Robots" +__url__ = "https://github.com/compas-rrc/compas_rrc" +__version__ = "1.1.0" +__author__ = "ETH Zurich" +__author_email__ = "rrc@arch.ethz.ch" +__license__ = "MIT license" +__copyright__ = "Copyright 2019 ETH Zurich" -__all__ = ['__author__', '__author_email__', '__copyright__', '__description__', '__license__', '__title__', '__url__', '__version__'] +__all__ = [ + "__author__", + "__author_email__", + "__copyright__", + "__description__", + "__license__", + "__title__", + "__url__", + "__version__", +] diff --git a/src/compas_rrc/client.py b/src/compas_rrc/client.py index 0c3e2ec5..dbd43af5 100644 --- a/src/compas_rrc/client.py +++ b/src/compas_rrc/client.py @@ -8,22 +8,23 @@ from .common import FutureResult from .common import InstructionException -__all__ = ['RosClient', 'AbbClient'] +__all__ = ["RosClient", "AbbClient"] -FEEDBACK_ERROR_PREFIX = 'Done FError ' +FEEDBACK_ERROR_PREFIX = "Done FError " def _get_key(message): - return 'msg:{}'.format(message.sequence_id) + return "msg:{}".format(message.sequence_id) def _get_response_key(message): - return 'msg:{}'.format(message['feedback_id']) + return "msg:{}".format(message["feedback_id"]) class SequenceCounter(object): """An atomic, thread-safe sequence increament counter.""" + ROLLOVER_THRESHOLD = 1000000 def __init__(self, start=0): @@ -49,7 +50,7 @@ def value(self): def default_feedback_parser(result): - feedback_value = result['feedback'] + feedback_value = result["feedback"] if feedback_value.startswith(FEEDBACK_ERROR_PREFIX): return InstructionException(feedback_value, result) @@ -103,7 +104,7 @@ class AbbClient(object): """ - def __init__(self, ros, namespace='/rob1'): + def __init__(self, ros, namespace="/rob1"): """Initialize a new robot client instance. Parameters @@ -116,53 +117,77 @@ def __init__(self, ros, namespace='/rob1'): """ self.ros = ros self.counter = SequenceCounter() - if not namespace.endswith('/'): - namespace += '/' + if not namespace.endswith("/"): + namespace += "/" self._version_checked = False - self._server_protocol_check = dict(event=threading.Event(), - param=roslibpy.Param(ros, namespace + 'protocol_version'), - version=None) + self._server_protocol_check = dict( + event=threading.Event(), + param=roslibpy.Param(ros, namespace + "protocol_version"), + version=None, + ) self.ros.on_ready(self.version_check) - self.topic = roslibpy.Topic(ros, namespace + 'robot_command', 'compas_rrc_driver/RobotMessage', queue_size=None) - self.feedback = roslibpy.Topic(ros, namespace + 'robot_response', 'compas_rrc_driver/RobotMessage', queue_size=0) + self.topic = roslibpy.Topic( + ros, + namespace + "robot_command", + "compas_rrc_driver/RobotMessage", + queue_size=None, + ) + self.feedback = roslibpy.Topic( + ros, + namespace + "robot_response", + "compas_rrc_driver/RobotMessage", + queue_size=0, + ) self.feedback.subscribe(self.feedback_callback) self.topic.advertise() self.futures = {} - self.ros.on('closing', self._disconnect_topics) + self.ros.on("closing", self._disconnect_topics) def version_check(self): """Check if the protocol version on the server matches the protocol version on the client.""" - self._server_protocol_check['version'] = self._server_protocol_check['param'].get() + self._server_protocol_check["version"] = self._server_protocol_check[ + "param" + ].get() # No version is usually caused by wrong namespace in the connection, check that and raise correct error - if self._server_protocol_check['version'] is None: + if self._server_protocol_check["version"] is None: params = self.ros.get_params() detected_namespaces = set() tentative_namespaces = set() for param in params: - if param.endswith('/robot_state_port') or param.endswith('/protocol_version'): - namespace = param[:param.rindex('/')] + if param.endswith("/robot_state_port") or param.endswith( + "/protocol_version" + ): + namespace = param[: param.rindex("/")] if namespace not in tentative_namespaces: tentative_namespaces.add(namespace) else: detected_namespaces.add(namespace) - raise Exception('Cannot find the specified namespace. Detected namespaces={}'.format(sorted(detected_namespaces))) + raise Exception( + "Cannot find the specified namespace. Detected namespaces={}".format( + sorted(detected_namespaces) + ) + ) - self._server_protocol_check['event'].set() + self._server_protocol_check["event"].set() def ensure_protocol_version(self): """Ensure protocol version on the server matches the protocol version on the client.""" if self._version_checked: return - if not self._server_protocol_check['version']: - if not self._server_protocol_check['event'].wait(10): - raise Exception('Could not yet retrieve server protocol version') + if not self._server_protocol_check["version"]: + if not self._server_protocol_check["event"].wait(10): + raise Exception("Could not yet retrieve server protocol version") - if self._server_protocol_check['version'] != CLIENT_PROTOCOL_VERSION: - raise Exception('Protocol version mismatch. Server={}, Client={}'.format(self._server_protocol_check['version'], CLIENT_PROTOCOL_VERSION)) + if self._server_protocol_check["version"] != CLIENT_PROTOCOL_VERSION: + raise Exception( + "Protocol version mismatch. Server={}, Client={}".format( + self._server_protocol_check["version"], CLIENT_PROTOCOL_VERSION + ) + ) self._version_checked = True @@ -227,7 +252,11 @@ def send(self, instruction): if instruction.feedback_level > 0: result = FutureResult() - parser = instruction.parse_feedback if hasattr(instruction, 'parse_feedback') else None + parser = ( + instruction.parse_feedback + if hasattr(instruction, "parse_feedback") + else None + ) self.futures[key] = dict(result=result, parser=parser) self.topic.publish(roslibpy.Message(instruction.msg)) @@ -292,7 +321,11 @@ def send_and_subscribe(self, instruction, callback): key = _get_key(instruction) - parser = instruction.parse_feedback if hasattr(instruction, 'parse_feedback') else None + parser = ( + instruction.parse_feedback + if hasattr(instruction, "parse_feedback") + else None + ) self.futures[key] = dict(callback=callback, parser=parser) self.topic.publish(roslibpy.Message(instruction.msg)) @@ -304,13 +337,13 @@ def feedback_callback(self, message): if future: result = message - if future['parser']: - result = future['parser'](result) + if future["parser"]: + result = future["parser"](result) else: result = default_feedback_parser(result) - if 'result' in future: - future['result']._set_result(result) + if "result" in future: + future["result"]._set_result(result) self.futures.pop(response_key) - elif 'callback' in future: - future['callback'](result) + elif "callback" in future: + future["callback"](result) # TODO: Handle unsubscribes diff --git a/src/compas_rrc/custom.py b/src/compas_rrc/custom.py index b55889b2..687b3de8 100644 --- a/src/compas_rrc/custom.py +++ b/src/compas_rrc/custom.py @@ -3,7 +3,7 @@ from compas_rrc.common import ExecutionLevel from compas_rrc.common import FeedbackLevel -__all__ = ['CustomInstruction'] +__all__ = ["CustomInstruction"] class CustomInstruction(ROSmsg): @@ -24,7 +24,14 @@ class CustomInstruction(ROSmsg): """ - def __init__(self, name, string_values=[], float_values=[], feedback_level=FeedbackLevel.NONE, execution_level=ExecutionLevel.ROBOT): + def __init__( + self, + name, + string_values=[], + float_values=[], + feedback_level=FeedbackLevel.NONE, + execution_level=ExecutionLevel.ROBOT, + ): """Create a new instance of the instruction. Parameters diff --git a/src/compas_rrc/io.py b/src/compas_rrc/io.py index 5ca28cab..e321bfa3 100644 --- a/src/compas_rrc/io.py +++ b/src/compas_rrc/io.py @@ -3,16 +3,16 @@ from compas_rrc.common import ExecutionLevel from compas_rrc.common import FeedbackLevel -INSTRUCTION_PREFIX = 'r_RRC_' +INSTRUCTION_PREFIX = "r_RRC_" __all__ = [ - 'SetDigital', - 'SetAnalog', - 'SetGroup', - 'PulseDigital', - 'ReadAnalog', - 'ReadDigital', - 'ReadGroup', + "SetDigital", + "SetAnalog", + "SetGroup", + "PulseDigital", + "ReadAnalog", + "ReadDigital", + "ReadGroup", ] @@ -48,7 +48,7 @@ def __init__(self, io_name, value, feedback_level=FeedbackLevel.NONE): """ if value not in (0, 1): raise ValueError("Value can only be 0 or 1") - self.instruction = INSTRUCTION_PREFIX + 'SetDigital' + self.instruction = INSTRUCTION_PREFIX + "SetDigital" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [io_name] @@ -85,7 +85,7 @@ def __init__(self, io_name, value, feedback_level=FeedbackLevel.NONE): feedback_level : :obj:`int` Defines the feedback level requested from the robot. Defaults to :attr:`FeedbackLevel.NONE`. """ - self.instruction = INSTRUCTION_PREFIX + 'SetAnalog' + self.instruction = INSTRUCTION_PREFIX + "SetAnalog" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [io_name] @@ -122,7 +122,7 @@ def __init__(self, io_name, value, feedback_level=FeedbackLevel.NONE): feedback_level : :obj:`int` Defines the feedback level requested from the robot. Defaults to :attr:`FeedbackLevel.NONE`. """ - self.instruction = INSTRUCTION_PREFIX + 'SetGroup' + self.instruction = INSTRUCTION_PREFIX + "SetGroup" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [io_name] @@ -158,7 +158,7 @@ def __init__(self, io_name, pulse_time, feedback_level=FeedbackLevel.NONE): feedback_level : :obj:`int` Defines the feedback level requested from the robot. Defaults to :attr:`FeedbackLevel.NONE`. """ - self.instruction = INSTRUCTION_PREFIX + 'PulseDigital' + self.instruction = INSTRUCTION_PREFIX + "PulseDigital" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [io_name] @@ -189,7 +189,7 @@ def __init__(self, io_name): io_name : :obj:`str` Name of the input signal. """ - self.instruction = INSTRUCTION_PREFIX + 'ReadAnalog' + self.instruction = INSTRUCTION_PREFIX + "ReadAnalog" self.feedback_level = FeedbackLevel.DONE self.exec_level = ExecutionLevel.ROBOT self.string_values = [io_name] @@ -203,7 +203,7 @@ def parse_feedback(self, result): Current value of the input signal. """ # read input value - result = result['float_values'][0] + result = result["float_values"][0] return result @@ -231,7 +231,7 @@ def __init__(self, io_name): io_name : :obj:`str` Name of the input signal. """ - self.instruction = INSTRUCTION_PREFIX + 'ReadDigital' + self.instruction = INSTRUCTION_PREFIX + "ReadDigital" self.feedback_level = FeedbackLevel.DONE self.exec_level = ExecutionLevel.ROBOT self.string_values = [io_name] @@ -246,7 +246,7 @@ def parse_feedback(self, result): """ # read input value - result = int(result['float_values'][0]) + result = int(result["float_values"][0]) return result @@ -274,7 +274,7 @@ def __init__(self, io_name): io_name : :obj:`str` Name of the input signal. """ - self.instruction = INSTRUCTION_PREFIX + 'ReadGroup' + self.instruction = INSTRUCTION_PREFIX + "ReadGroup" self.feedback_level = FeedbackLevel.DONE self.exec_level = ExecutionLevel.ROBOT self.string_values = [io_name] @@ -289,5 +289,5 @@ def parse_feedback(self, result): """ # read input value - result = int(result['float_values'][0]) + result = int(result["float_values"][0]) return result diff --git a/src/compas_rrc/motion.py b/src/compas_rrc/motion.py index 59fee958..95b418be 100644 --- a/src/compas_rrc/motion.py +++ b/src/compas_rrc/motion.py @@ -3,14 +3,14 @@ from compas_rrc.common import ExecutionLevel from compas_rrc.common import FeedbackLevel -INSTRUCTION_PREFIX = 'r_RRC_' +INSTRUCTION_PREFIX = "r_RRC_" __all__ = [ - 'Zone', - 'Motion', - 'MoveToJoints', - 'MoveToFrame', - 'MoveToRobtarget', + "Zone", + "Motion", + "MoveToJoints", + "MoveToFrame", + "MoveToRobtarget", ] @@ -123,10 +123,11 @@ class Motion(object): .. autoattribute:: LINEAR .. autoattribute:: JOINT """ - LINEAR = 'L' + + LINEAR = "L" """Moves the robot linearly to the specified position.""" - JOINT = 'J' + JOINT = "J" """Moves the robot not linearly to the specified position by coordinating all joints to start and end together. This type of motion can be faster than LINEAR motion.""" @@ -155,7 +156,9 @@ class MoveToJoints(ROSmsg): """ - def __init__(self, joints, ext_axes, speed, zone, feedback_level=FeedbackLevel.NONE): + def __init__( + self, joints, ext_axes, speed, zone, feedback_level=FeedbackLevel.NONE + ): """Create a new instance of the instruction. Parameters @@ -175,30 +178,36 @@ def __init__(self, joints, ext_axes, speed, zone, feedback_level=FeedbackLevel.N the motion planner has executed the instruction fully. """ if speed <= 0: - raise ValueError('Speed must be higher than zero. Current value={}'.format(speed)) + raise ValueError( + "Speed must be higher than zero. Current value={}".format(speed) + ) - self.instruction = INSTRUCTION_PREFIX + 'MoveToJoints' + self.instruction = INSTRUCTION_PREFIX + "MoveToJoints" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT joints = joints or [] if len(joints) > 6: - raise ValueError('Only up to 6 joints are supported') + raise ValueError("Only up to 6 joints are supported") joints_pad = [0.0] * (6 - len(joints)) ext_axes = ext_axes or [] if len(ext_axes) > 6: - raise ValueError('Only up to 6 external axes are supported') + raise ValueError("Only up to 6 external axes are supported") ext_axes_pad = [0.0] * (6 - len(ext_axes)) self.string_values = [] - self.float_values = list(joints) + joints_pad + list(ext_axes) + ext_axes_pad + [speed, zone] + self.float_values = ( + list(joints) + joints_pad + list(ext_axes) + ext_axes_pad + [speed, zone] + ) class MoveGeneric(ROSmsg): def __init__(self, frame, ext_axes, speed, zone, feedback_level=FeedbackLevel.NONE): if speed <= 0: - raise ValueError('Speed must be higher than zero. Current value={}'.format(speed)) + raise ValueError( + "Speed must be higher than zero. Current value={}".format(speed) + ) self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT @@ -208,7 +217,7 @@ def __init__(self, frame, ext_axes, speed, zone, feedback_level=FeedbackLevel.NO ext_axes = ext_axes or [] if len(ext_axes) > 6: - raise ValueError('Only up to 6 external axes are supported') + raise ValueError("Only up to 6 external axes are supported") ext_axes_pad = [0.0] * (6 - len(ext_axes)) self.string_values = [] @@ -240,7 +249,14 @@ class MoveToFrame(MoveGeneric): """ - def __init__(self, frame, speed, zone, motion_type=Motion.JOINT, feedback_level=FeedbackLevel.NONE): + def __init__( + self, + frame, + speed, + zone, + motion_type=Motion.JOINT, + feedback_level=FeedbackLevel.NONE, + ): """Create a new instance of the instruction. Parameters @@ -260,9 +276,9 @@ def __init__(self, frame, speed, zone, motion_type=Motion.JOINT, feedback_level= the motion planner has executed the instruction fully. """ super(MoveToFrame, self).__init__(frame, [], speed, zone, feedback_level) - instruction = 'MoveTo' + instruction = "MoveTo" self.instruction = INSTRUCTION_PREFIX + instruction - self.string_values = ['FrameJ'] if motion_type == Motion.JOINT else ['FrameL'] + self.string_values = ["FrameJ"] if motion_type == Motion.JOINT else ["FrameL"] class MoveToRobtarget(MoveGeneric): @@ -289,7 +305,15 @@ class MoveToRobtarget(MoveGeneric): """ - def __init__(self, frame, ext_axes, speed, zone, motion_type=Motion.JOINT, feedback_level=FeedbackLevel.NONE): + def __init__( + self, + frame, + ext_axes, + speed, + zone, + motion_type=Motion.JOINT, + feedback_level=FeedbackLevel.NONE, + ): """Create a new instance of the instruction. Parameters @@ -310,7 +334,9 @@ def __init__(self, frame, ext_axes, speed, zone, motion_type=Motion.JOINT, feedb Use :attr:`FeedbackLevel.DONE` and :attr:`Zone.FINE` together to make sure the motion planner has executed the instruction fully. """ - super(MoveToRobtarget, self).__init__(frame, ext_axes, speed, zone, feedback_level) - instruction = 'MoveTo' + super(MoveToRobtarget, self).__init__( + frame, ext_axes, speed, zone, feedback_level + ) + instruction = "MoveTo" self.instruction = INSTRUCTION_PREFIX + instruction - self.string_values = ['J'] if motion_type == Motion.JOINT else ['L'] + self.string_values = ["J"] if motion_type == Motion.JOINT else ["L"] diff --git a/src/compas_rrc/msg.py b/src/compas_rrc/msg.py index a76eb368..019d2b59 100644 --- a/src/compas_rrc/msg.py +++ b/src/compas_rrc/msg.py @@ -3,11 +3,9 @@ from compas_rrc.common import ExecutionLevel from compas_rrc.common import FeedbackLevel -INSTRUCTION_PREFIX = 'r_RRC_' +INSTRUCTION_PREFIX = "r_RRC_" -__all__ = [ - 'PrintText' -] +__all__ = ["PrintText"] class PrintText(ROSmsg): @@ -38,7 +36,7 @@ def __init__(self, text, feedback_level=FeedbackLevel.NONE): """ if len(text) > 80: raise ValueError("text can only be up to 80 chars") - self.instruction = INSTRUCTION_PREFIX + 'PrintText' + self.instruction = INSTRUCTION_PREFIX + "PrintText" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [text] diff --git a/src/compas_rrc/utility.py b/src/compas_rrc/utility.py index 186d3ab0..724f53cb 100644 --- a/src/compas_rrc/utility.py +++ b/src/compas_rrc/utility.py @@ -6,19 +6,21 @@ from compas_rrc.common import FeedbackLevel from compas_rrc.common import RobotJoints -INSTRUCTION_PREFIX = 'r_RRC_' - -__all__ = ['Noop', - 'GetFrame', - 'GetJoints', - 'GetRobtarget', - 'SetAcceleration', - 'SetTool', - 'SetMaxSpeed', - 'Stop', - 'WaitTime', - 'SetWorkObject', - 'Debug'] +INSTRUCTION_PREFIX = "r_RRC_" + +__all__ = [ + "Noop", + "GetFrame", + "GetJoints", + "GetRobtarget", + "SetAcceleration", + "SetTool", + "SetMaxSpeed", + "Stop", + "WaitTime", + "SetWorkObject", + "Debug", +] def is_rapid_none(val): @@ -50,7 +52,7 @@ def __init__(self, feedback_level=FeedbackLevel.NONE): feedback_level : :obj:`int` Defines the feedback level requested from the robot. Defaults to :attr:`FeedbackLevel.NONE`. """ - self.instruction = INSTRUCTION_PREFIX + 'Noop' + self.instruction = INSTRUCTION_PREFIX + "Noop" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [] @@ -152,7 +154,7 @@ class GetJoints(ROSmsg): def __init__(self): """Create a new instance of the instruction.""" - self.instruction = INSTRUCTION_PREFIX + 'GetJoints' + self.instruction = INSTRUCTION_PREFIX + "GetJoints" self.feedback_level = FeedbackLevel.DONE self.exec_level = ExecutionLevel.ROBOT self.string_values = [] @@ -167,10 +169,14 @@ def parse_feedback(self, result): Current joints and external axes of the robot. """ # read robot joints - robot_joints = [result['float_values'][i] for i in range(0, 6)] + robot_joints = [result["float_values"][i] for i in range(0, 6)] # read external axes - external_axes = [result['float_values'][i] for i in range(6, 12) if not is_rapid_none(result['float_values'][i])] + external_axes = [ + result["float_values"][i] + for i in range(6, 12) + if not is_rapid_none(result["float_values"][i]) + ] # write result return RobotJoints(*robot_joints), ExternalAxes(*external_axes) @@ -195,7 +201,7 @@ class GetRobtarget(ROSmsg): def __init__(self): """Create a new instance of the instruction.""" - self.instruction = INSTRUCTION_PREFIX + 'GetRobtarget' + self.instruction = INSTRUCTION_PREFIX + "GetRobtarget" self.feedback_level = FeedbackLevel.DONE self.exec_level = ExecutionLevel.ROBOT self.string_values = [] @@ -211,20 +217,24 @@ def parse_feedback(self, result): """ # read pos - x = result['float_values'][0] - y = result['float_values'][1] - z = result['float_values'][2] + x = result["float_values"][0] + y = result["float_values"][1] + z = result["float_values"][2] pos = [x, y, z] # read orient - orient_q1 = result['float_values'][3] - orient_q2 = result['float_values'][4] - orient_q3 = result['float_values'][5] - orient_q4 = result['float_values'][6] + orient_q1 = result["float_values"][3] + orient_q2 = result["float_values"][4] + orient_q3 = result["float_values"][5] + orient_q4 = result["float_values"][6] orientation = [orient_q1, orient_q2, orient_q3, orient_q4] # read gantry joints - external_axes = [result['float_values'][i] for i in range(7, 13) if not is_rapid_none(result['float_values'][i])] + external_axes = [ + result["float_values"][i] + for i in range(7, 13) + if not is_rapid_none(result["float_values"][i]) + ] # write result @@ -292,7 +302,7 @@ def __init__(self, acc, ramp, feedback_level=FeedbackLevel.NONE): feedback_level : :obj:`int` Defines the feedback level requested from the robot. Defaults to :attr:`FeedbackLevel.NONE`. """ - self.instruction = INSTRUCTION_PREFIX + 'SetAcceleration' + self.instruction = INSTRUCTION_PREFIX + "SetAcceleration" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [] @@ -325,7 +335,7 @@ def __init__(self, tool_name, feedback_level=FeedbackLevel.NONE): feedback_level : :obj:`int` Defines the feedback level requested from the robot. Defaults to :attr:`FeedbackLevel.NONE`. """ - self.instruction = INSTRUCTION_PREFIX + 'SetTool' + self.instruction = INSTRUCTION_PREFIX + "SetTool" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [tool_name] @@ -365,7 +375,7 @@ def __init__(self, override, max_tcp, feedback_level=FeedbackLevel.NONE): feedback_level : :obj:`int` Defines the feedback level requested from the robot. Defaults to :attr:`FeedbackLevel.NONE`. """ - self.instruction = INSTRUCTION_PREFIX + 'SetMaxSpeed' + self.instruction = INSTRUCTION_PREFIX + "SetMaxSpeed" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [] @@ -398,7 +408,7 @@ def __init__(self, wobj_name, feedback_level=FeedbackLevel.NONE): feedback_level : :obj:`int` Defines the feedback level requested from the robot. Defaults to :attr:`FeedbackLevel.NONE`. """ - self.instruction = INSTRUCTION_PREFIX + 'SetWorkObject' + self.instruction = INSTRUCTION_PREFIX + "SetWorkObject" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [wobj_name] @@ -429,7 +439,7 @@ def __init__(self, feedback_level=FeedbackLevel.NONE): feedback_level : :obj:`int` Defines the feedback level requested from the robot. Defaults to :attr:`FeedbackLevel.NONE`. """ - self.instruction = INSTRUCTION_PREFIX + 'Stop' + self.instruction = INSTRUCTION_PREFIX + "Stop" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [] @@ -463,7 +473,7 @@ def __init__(self, time, feedback_level=FeedbackLevel.NONE): feedback_level : :obj:`int` Defines the feedback level requested from the robot. Defaults to :attr:`FeedbackLevel.NONE`. """ - self.instruction = INSTRUCTION_PREFIX + 'WaitTime' + self.instruction = INSTRUCTION_PREFIX + "WaitTime" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [] diff --git a/src/compas_rrc/watch.py b/src/compas_rrc/watch.py index 73ba425f..41226457 100644 --- a/src/compas_rrc/watch.py +++ b/src/compas_rrc/watch.py @@ -3,12 +3,12 @@ from compas_rrc.common import ExecutionLevel from compas_rrc.common import FeedbackLevel -INSTRUCTION_PREFIX = 'r_RRC_' +INSTRUCTION_PREFIX = "r_RRC_" __all__ = [ - 'ReadWatch', - 'StartWatch', - 'StopWatch', + "ReadWatch", + "StartWatch", + "StopWatch", ] @@ -30,7 +30,7 @@ class ReadWatch(ROSmsg): def __init__(self): """Create a new instance of the instruction.""" - self.instruction = INSTRUCTION_PREFIX + 'ReadWatch' + self.instruction = INSTRUCTION_PREFIX + "ReadWatch" self.feedback_level = FeedbackLevel.DONE self.exec_level = ExecutionLevel.ROBOT self.string_values = [] @@ -45,7 +45,7 @@ def parse_feedback(self, result): Current value of the watch in seconds. """ # read input value - result = round(result['float_values'][0], 3) + result = round(result["float_values"][0], 3) return result @@ -73,7 +73,7 @@ def __init__(self, feedback_level=FeedbackLevel.NONE): feedback_level : :obj:`int` Defines the feedback level requested from the robot. Defaults to :attr:`FeedbackLevel.NONE`. """ - self.instruction = INSTRUCTION_PREFIX + 'StartWatch' + self.instruction = INSTRUCTION_PREFIX + "StartWatch" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [] @@ -104,7 +104,7 @@ def __init__(self, feedback_level=FeedbackLevel.NONE): feedback_level : :obj:`int` Defines the feedback level requested from the robot. Defaults to :attr:`FeedbackLevel.NONE`. """ - self.instruction = INSTRUCTION_PREFIX + 'StopWatch' + self.instruction = INSTRUCTION_PREFIX + "StopWatch" self.feedback_level = feedback_level self.exec_level = ExecutionLevel.ROBOT self.string_values = [] diff --git a/tests/ipy_test_runner.py b/tests/ipy_test_runner.py index c0fe63e5..21aae1ff 100644 --- a/tests/ipy_test_runner.py +++ b/tests/ipy_test_runner.py @@ -6,9 +6,9 @@ HERE = os.path.dirname(__file__) -if __name__ == '__main__': +if __name__ == "__main__": # Fake Rhino modules - pytest.load_fake_module('Rhino') - pytest.load_fake_module('Rhino.Geometry', fake_types=['RTree', 'Sphere', 'Point3d']) + pytest.load_fake_module("Rhino") + pytest.load_fake_module("Rhino.Geometry", fake_types=["RTree", "Sphere", "Point3d"]) pytest.run(HERE) diff --git a/tests/test_client.py b/tests/test_client.py index 3c48e87a..84fbd34c 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -39,7 +39,7 @@ def incrementer(c): threads = [] for _ in range(nr_of_threads): - t = threading.Thread(target=incrementer, args=(counter, )) + t = threading.Thread(target=incrementer, args=(counter,)) t.start() threads.append(t) diff --git a/tests/test_motion.py b/tests/test_motion.py index 36d56171..bb4f41fc 100644 --- a/tests/test_motion.py +++ b/tests/test_motion.py @@ -34,21 +34,61 @@ def test_move_to_joints_validation(): def test_move_to_frame(): inst = rrc.MoveToFrame(Frame.worldXY(), 100, rrc.Zone.FINE, rrc.Motion.JOINT) - assert inst.float_values == [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 100, -1] - assert inst.string_values == ['FrameJ'] + assert inst.float_values == [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0, + 0, + 0, + 0, + 0, + 0, + 100, + -1, + ] + assert inst.string_values == ["FrameJ"] inst = rrc.MoveToFrame(Frame.worldXY(), 100, rrc.Zone.FINE, rrc.Motion.LINEAR) - assert inst.string_values == ['FrameL'] + assert inst.string_values == ["FrameL"] def test_move_to_robtarget(): - inst = rrc.MoveToRobtarget(Frame.worldXY(), [50, 20], 100, rrc.Zone.FINE, rrc.Motion.JOINT) - - assert inst.float_values == [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 50, 20, 0, 0, 0, 0, 100, -1] - assert inst.string_values == ['J'] + inst = rrc.MoveToRobtarget( + Frame.worldXY(), [50, 20], 100, rrc.Zone.FINE, rrc.Motion.JOINT + ) + + assert inst.float_values == [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 50, + 20, + 0, + 0, + 0, + 0, + 100, + -1, + ] + assert inst.string_values == ["J"] def test_move_to_robtarget_validation(): # Only up to 6 external axes are supported with pytest.raises(ValueError): - rrc.MoveToRobtarget(Frame.worldXY(), [50, 20, 0, 0, 0, 0, 0, 0], 100, rrc.Zone.FINE, rrc.Motion.JOINT) + rrc.MoveToRobtarget( + Frame.worldXY(), + [50, 20, 0, 0, 0, 0, 0, 0], + 100, + rrc.Zone.FINE, + rrc.Motion.JOINT, + )