Skip to content

Commit b8474f4

Browse files
author
Andrew Lui
committed
move the tools modules to task_trees.tools to avoid potential name clashes when task trees work with other packages. remove demos from the module list in the setup.py file. Update rviz_tools.py to make it the same release as rviz_marker_tool which include publishing of MarkerArray
. Modified the BasicTask class and remove all pose specific parameters and functions to recover its intention as a generic task class.
1 parent 726c279 commit b8474f4

32 files changed

+923
-145
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ include_directories(
163163
## Mark executable scripts (Python etc.) for installation
164164
## in contrast to setup.py, you can choose the destination
165165
catkin_install_python(PROGRAMS
166-
demos/pushblock/demo.py
166+
task_trees/demos/pushblock/demo.py
167167
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
168168
)
169169

demos/gridscan/behaviours_advanced.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
from py_trees.common import Status
1616
# robot control module
1717
from task_scene_gridscan import GridScanScene
18-
from tools.logging_tools import logger
19-
from demos.gridscan.behaviours_gridscan import DoMoveTankGrid
18+
from task_trees.tools.logging_tools import logger
19+
from behaviours_gridscan import DoMoveTankGrid
2020

2121
# -----------------------------------------------------------------------------------------------------
2222
# Advanced behaviours for illustrating the versatility of the ConditionalCommanderBehaviour base class

demos/gridscan/behaviours_gridscan.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# robot control module
1717
from task_trees.behaviours_move import SceneConditionalCommanderBehaviour
1818
from task_scene_gridscan import GridScanScene
19-
from tools.logging_tools import logger
19+
from task_trees.tools.logging_tools import logger
2020

2121
# ----------------------------------------------------------------------
2222
# Custom Behaviour Classes

demos/gridscan/task_trees_manager_gridscan.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323
from task_trees.behaviours_base import *
2424
from task_trees.task_trees_manager import BasicTaskTreesManager, TaskTreesManager, BasicTask, TaskStates
2525
from task_trees.scene_to_rviz import SceneToRViz
26-
from demos.gridscan.behaviours_gridscan import SimCalibrate, DoMoveTankGrid
27-
from demos.gridscan.behaviours_advanced import DoMoveTankGridVisualCDROS
26+
from behaviours_gridscan import SimCalibrate, DoMoveTankGrid
27+
from behaviours_advanced import DoMoveTankGridVisualCDROS
2828

29-
from tools.logging_tools import logger
30-
import tools.pose_tools as pose_tools
29+
from task_trees.tools.logging_tools import logger
30+
import task_trees.tools.pose_tools as pose_tools
3131
# -------------------------------------
3232
# Tasks specialized for this application
3333

@@ -55,6 +55,7 @@ def __init__(self, named_pose:str):
5555
class MoveGridPoseTask(BasicTask):
5656
def __init__(self, tile_x:int, tile_y:int, cell_x:int, cell_y:int):
5757
super(MoveGridPoseTask, self).__init__([tile_x, tile_y, cell_x, cell_y])
58+
5859

5960
# ----------------------------------------
6061
# The TaskManager specialized for this application
@@ -118,20 +119,20 @@ def query_grid_position_of_task(self):
118119
"""
119120
if not self.the_blackboard.exists('task'):
120121
raise TypeError(f'unable to query logical pose due to no task has been submitted')
121-
return self.the_blackboard.task.get_goal_as_logical_pose()
122+
return self.the_blackboard.task.get_param()
122123

123124
# return the logical rotation of the accepted task, or raise TypeError if no task is submitted
124125
def query_logical_rpy_of_task(self):
125126
if not self.the_blackboard.exists('task'):
126127
raise TypeError(f'unable to query logical rotation due to no task has been submitted')
127-
grid_position = self.the_blackboard.task.get_goal_as_logical_pose()
128+
grid_position = self.the_blackboard.task.get_param()
128129
rpy = self.the_scene.compute_rpy_from_grid_position(grid_position)
129130
return rpy
130131

131132
# internal function for obtaining the logical pose of the current task as xyzrpy
132133
def _get_task_target_xyzrpy(self) -> list:
133134
if self.the_blackboard.exists('task'):
134-
logical_pose = self.the_blackboard.task.get_goal_as_logical_pose()
135+
logical_pose = self.the_blackboard.task.get_param()
135136
return self.the_scene.compute_xyzrpy_from_grid_position(logical_pose)
136137
return False
137138

demos/pickndrop/behaviours_pnd.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# robot control module
1414
import arm_commander.tools.moveit_tools as moveit_tools
1515
from task_trees.behaviours_base import ConditionalBehaviour, ConditionalCommanderBehaviour
16-
from tools.logging_tools import logger
16+
from task_trees.tools.logging_tools import logger
1717
from scan_model import ScanRegionModel
1818

1919
# ----------------------------------------------------------------------

demos/pickndrop/demo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from arm_commander.commander_moveit import GeneralCommander
1919
from task_trees_manager_pnd import PNDTaskTreesManager, ScanTask, PickUpObjectTask, DropObjectTask
2020
from task_trees.states import TaskStates
21-
from tools.logging_tools import logger
21+
from task_trees.tools.logging_tools import logger
2222
# -- Test cases specialized for the PickNDrop Demo
2323

2424
class DemoStates(Enum):

demos/pickndrop/task_trees_manager_pnd.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
from task_trees.task_trees_manager import TaskTreesManager, BasicTask
2323
from task_trees.task_scene import Scene
2424
from task_trees.scene_to_rviz import SceneToRViz
25-
import tools.pose_tools as pose_tools
26-
from demos.pickndrop.behaviours_pnd import DoScanProgram
25+
import task_trees.tools.pose_tools as pose_tools
26+
from behaviours_pnd import DoScanProgram
2727
from scan_model import SingleLineScanModel, SteppingScanModel, FourCornersScanModel
2828

2929
# -------------------------------------
@@ -52,6 +52,8 @@ class PickUpObjectTask(BasicTask):
5252
def __init__(self, xyz_world:list):
5353
super(PickUpObjectTask, self).__init__()
5454
self.xyz = xyz_world
55+
def get_xyz(self):
56+
return self.xyz
5557

5658

5759
class DropObjectTask(BasicTask):
@@ -62,7 +64,9 @@ def __init__(self):
6264
class MovePoseTask(BasicTask):
6365
def __init__(self, xyz_world:list):
6466
super(MovePoseTask, self).__init__()
65-
self.xyz = xyz_world
67+
self.xyz = xyz_world
68+
def get_xyz(self):
69+
return self.xyz
6670

6771
# ----------------------------------------
6872
# The TaskManager specialized for this application
@@ -161,7 +165,7 @@ def query_logical_pose_of_task(self):
161165
:rtype: unspecified as defined by the specific subclass of BasicTask
162166
"""
163167
if self.the_blackboard.exists('task'):
164-
return self.the_blackboard.task.get_goal_as_logical_pose()
168+
return self.the_blackboard.task.get_param()
165169
raise TypeError(f'unable to query logical pose due to no task has been submitted')
166170

167171
# return the target position of the accepted task, or raise TypeError if no task is submitted
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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()

demos/pickndrop_estop/task_trees_manager_pnd.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818

1919
# robot control module
2020
from arm_commander.commander_moveit import GeneralCommander, logger
21-
import tools.pose_tools as pose_tools
21+
import task_trees.tools.pose_tools as pose_tools
2222

2323
from task_trees.behaviours_base import SimAttachObject, SimDetachObject
2424
from task_trees.behaviours_move import DoMoveNamedPose, DoMoveXYZ
2525
from task_trees.task_trees_manager import GuardedTaskTreesManager, BasicTask
2626
from task_trees.task_scene import Scene
2727

28-
from demos.pickndrop.behaviours_pnd import DoScanProgram
28+
from behaviours_pnd import DoScanProgram
2929
from scan_model import SingleLineScanModel, SteppingScanModel, FourCornersScanModel
3030

3131
# -------------------------------------
@@ -54,18 +54,20 @@ class PickUpObjectTask(BasicTask):
5454
def __init__(self, xyz_world:list):
5555
super(PickUpObjectTask, self).__init__()
5656
self.xyz = xyz_world
57-
57+
def get_xyz(self):
58+
return self.xyz
5859

5960
class DropObjectTask(BasicTask):
6061
def __init__(self):
6162
super(DropObjectTask, self).__init__()
62-
6363

6464
class MovePoseTask(BasicTask):
6565
def __init__(self, xyz_world:list):
6666
super(MovePoseTask, self).__init__()
6767
self.xyz = xyz_world
68-
68+
def get_xyz(self):
69+
return self.xyz
70+
6971
# ----------------------------------------
7072
# The TaskManager specialized for this application
7173
class PNDTaskTreesManager(GuardedTaskTreesManager):
@@ -157,7 +159,7 @@ def query_logical_pose_of_task(self):
157159
:rtype: unspecified as defined by the specific subclass of BasicTask
158160
"""
159161
if self.the_blackboard.exists('task'):
160-
return self.the_blackboard.task.get_goal_as_logical_pose()
162+
return self.the_blackboard.task.get_param()
161163
raise TypeError(f'unable to query logical pose due to no task has been submitted')
162164

163165
# return the target position of the accepted task, or raise TypeError if no task is submitted

demos/pushblock/task_trees_manager_pushblock.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from task_trees.task_trees_manager import TaskTreesManager, BasicTask
2626
from task_trees.task_scene import Scene
2727
from task_trees.scene_to_rviz import SceneToRViz
28-
import tools.pose_tools as pose_tools
28+
import task_trees.tools.pose_tools as pose_tools
2929
# -------------------------------------
3030
# Tasks specialized for the Pick-n-Drop
3131

@@ -140,7 +140,7 @@ def query_logical_pose_of_task(self):
140140
:rtype: unspecified as defined by the specific subclass of BasicTask
141141
"""
142142
if self.the_blackboard.exists('task'):
143-
return self.the_blackboard.task.get_goal_as_logical_pose()
143+
return self.the_blackboard.task.get_param()
144144
raise TypeError(f'unable to query logical pose due to no task has been submitted')
145145

146146
def query_current_reference_frame(self):
@@ -155,15 +155,15 @@ def query_target_reference_frame(self):
155155
:rtype: str
156156
"""
157157
if self.the_blackboard.exists('task'):
158-
target = self.the_blackboard.task.get_goal_as_logical_pose()
158+
target = self.the_blackboard.task.get_param()
159159
return target
160160
raise TypeError(f'unable to query the target due to no task has been submitted')
161161

162162
# return the ideal rotation of the end-effector for pushing to the target, which is derived from the target and the structure of the end-effector
163163
# defined in the config file
164164
def query_rotation_from_target(self):
165165
if self.the_blackboard.exists('task'):
166-
target = self.the_blackboard.task.get_goal_as_logical_pose()
166+
target = self.the_blackboard.task.get_param()
167167
rotation = self.the_scene.query_config(target + ".rotation")
168168
return rotation
169169
raise TypeError(f'unable to query the rotation due to no task has been submitted or the target area is wrong')

0 commit comments

Comments
 (0)