|
| 1 | +# Copyright 2024 - Andrew Kwok Fai LUI, |
| 2 | +# Robotics and Autonomous Systems Group, REF, RI |
| 3 | +# and the Queensland University of Technology |
| 4 | + |
| 5 | +__author__ = 'Andrew Lui' |
| 6 | +__copyright__ = 'Copyright 2024' |
| 7 | +__license__ = 'GPL' |
| 8 | +__version__ = '1.0' |
| 9 | +__email__ = 'ak.lui@qut.edu.au' |
| 10 | +__status__ = 'Development' |
| 11 | + |
| 12 | +from py_trees.common import Status |
| 13 | +# robot control module |
| 14 | +import arm_commander.tools.moveit_tools as moveit_tools |
| 15 | +from task_trees.behaviours_base import ConditionalBehaviour, ConditionalCommanderBehaviour |
| 16 | +from task_trees.tools.logging_tools import logger |
| 17 | +from scan_model import ScanRegionModel |
| 18 | + |
| 19 | +# ---------------------------------------------------------------------- |
| 20 | +# Behaviour Classes for the Pick-n-Drop robot arm manipulation application |
| 21 | + |
| 22 | +class DoScanProgram(ConditionalCommanderBehaviour): |
| 23 | + """ This behaviour moves the end-effector over a planar region according toa program |
| 24 | + The orientation of the end-effector is fixed. |
| 25 | + """ |
| 26 | + def __init__(self, name, condition_fn=True, condition_policy=None, arm_commander=None, scan_program:ScanRegionModel=None): |
| 27 | + """ the constructor, refers to the constructor ConditionalCommanderBehaviour for the description of the other parameters |
| 28 | + :param scan_program: the scan program |
| 29 | + :type scan_program: ScanRegionModel |
| 30 | + """ |
| 31 | + super(DoScanProgram, self).__init__(name=name, condition_fn=condition_fn, condition_policy=condition_policy, arm_commander=arm_commander) |
| 32 | + if scan_program is None: |
| 33 | + logger.error(f'{__class__.__name__} ({self.name}): parameter (scan_program) is None -> fix the missing value at behaviour construction') |
| 34 | + raise AssertionError(f'A parameter should not be None nor missing') |
| 35 | + self.scan_program:ScanRegionModel = scan_program |
| 36 | + # the concrete implementation of the logic when the General Commander is READY |
| 37 | + def update_when_ready(self): |
| 38 | + xyz = self.scan_program.get_next_xyz() |
| 39 | + if xyz is None: |
| 40 | + self.scan_program.reset() |
| 41 | + xyz = self.scan_program.get_next_xyz() |
| 42 | + |
| 43 | + # a heck to test the use of orientation constraint |
| 44 | + self.arm_commander.add_path_constraints(moveit_tools.create_path_orientation_constraint( |
| 45 | + self.arm_commander.END_EFFECTOR_LINK, self.arm_commander.pose_in_frame('the_table'), 0.05, 0.05, 6.28)) |
| 46 | + # send the command to the General Commander in an asynchronous manner |
| 47 | + self.arm_commander.move_to_position(x=xyz[0], y=xyz[1], z=xyz[2], cartesian=True, reference_frame='the_table', wait=False) |
| 48 | + logger.info(f'DoScanProgram ({self.name}): started move to pose: {xyz} in reference frame "the_table"') |
| 49 | + return Status.RUNNING |
| 50 | + # the concrete implementation of the logic when the command is completed |
| 51 | + def tidy_up(self): |
| 52 | + super().tidy_up() |
| 53 | + self.scan_program.done_current() |
| 54 | + self.arm_commander.clear_path_constraints() |
0 commit comments