Skip to content

Commit 66f3667

Browse files
multirobot revision 1
1 parent de1c8c2 commit 66f3667

4 files changed

Lines changed: 44 additions & 14 deletions

File tree

hello_helpers/src/hello_helpers/hello_misc.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -241,24 +241,36 @@ def main(self, node_name, node_topic_namespace, wait_for_first_pointcloud=True):
241241
rospy.signal_shutdown('Unable to connect to arm action server. Timeout exceeded.')
242242
sys.exit()
243243

244-
self._joint_states_subscriber = rospy.Subscriber('/stretch/joint_states', JointState, self._joint_states_callback)
245-
244+
if self.robot_name == None:
245+
self._joint_states_subscriber = rospy.Subscriber('/stretch/joint_states', JointState, self._joint_states_callback)
246+
else:
247+
self._joint_states_subscriber = rospy.Subscriber('/'+self.robot_name+'/joint_states', JointState, self._joint_states_callback)
248+
246249
self.tf2_buffer = tf2_ros.Buffer()
247250
self.tf2_listener = tf2_ros.TransformListener(self.tf2_buffer)
251+
if self.robot_name == None:
252+
self._tool_subscriber = rospy.Subscriber('/tool', String, self._tool_callback)
253+
self._mode_subscriber = rospy.Subscriber('/mode', String, self._mode_callback)
254+
self.point_cloud_subscriber = rospy.Subscriber('/camera/depth/color/points', PointCloud2, self._point_cloud_callback)
255+
else:
256+
self._tool_subscriber = rospy.Subscriber('/'+self.robot_name+'/tool', String, self._tool_callback)
257+
self._mode_subscriber = rospy.Subscriber('/'+self.robot_name+'/mode', String, self._mode_callback)
258+
self.point_cloud_subscriber = rospy.Subscriber('/'+self.robot_name+'/camera/depth/color/points', PointCloud2, self._point_cloud_callback)
248259

249-
self._tool_subscriber = rospy.Subscriber('/tool', String, self._tool_callback)
250-
self._mode_subscriber = rospy.Subscriber('/mode', String, self._mode_callback)
251-
252-
self.point_cloud_subscriber = rospy.Subscriber('/camera/depth/color/points', PointCloud2, self._point_cloud_callback)
253260
self.point_cloud_pub = rospy.Publisher('/' + node_topic_namespace + '/point_cloud2', PointCloud2, queue_size=1)
254261

255262
rospy.wait_for_service('/home_the_robot')
256263
rospy.wait_for_service('/stow_the_robot')
257264
rospy.wait_for_service('/stop_the_robot')
258265
rospy.loginfo('Node ' + self.node_name + ' connected to robot services.')
259-
self.home_the_robot_service = rospy.ServiceProxy('/home_the_robot', Trigger)
260-
self.stow_the_robot_service = rospy.ServiceProxy('/stow_the_robot', Trigger)
261-
self.stop_the_robot_service = rospy.ServiceProxy('/stop_the_robot', Trigger)
266+
if self.robot_name == None:
267+
self.home_the_robot_service = rospy.ServiceProxy('/home_the_robot', Trigger)
268+
self.stow_the_robot_service = rospy.ServiceProxy('/stow_the_robot', Trigger)
269+
self.stop_the_robot_service = rospy.ServiceProxy('/stop_the_robot', Trigger)
270+
else:
271+
self.home_the_robot_service = rospy.ServiceProxy('/'+self.robot_name+'/home_the_robot', Trigger)
272+
self.stow_the_robot_service = rospy.ServiceProxy('/'+self.robot_name+'/stow_the_robot', Trigger)
273+
self.stop_the_robot_service = rospy.ServiceProxy('/'+self.robot_name+'/stop_the_robot', Trigger)
262274

263275
if wait_for_first_pointcloud:
264276
# Do not start until a point cloud has been received

stretch_core/launch/stretch_driver.launch

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
<param name="robot_description" textfile="$(find stretch_description)/urdf/stretch.urdf" />
44
<arg name="calibrated_controller_yaml_file" value="$(find stretch_core)/config/controller_calibration_head.yaml"/>
5+
<arg name="enable_multi_robot" default="false" doc="Turn on namespacing of topics/services/actions to the robots unique name, thereby allowing control of multiple robots simultaneously." />
6+
<arg name="__enable_multi_robot_arg" value="$(eval '--enable_multi_robot' if arg('enable_multi_robot') else '')" />
57

68
<node
79
name="joint_state_publisher"
@@ -33,7 +35,7 @@
3335
<param name="publish_frequency" value="30.0"/>
3436
</node>
3537

36-
<node name="stretch_driver" pkg="stretch_core" type="stretch_driver" output="screen">
38+
<node name="stretch_driver" pkg="stretch_core" type="stretch_driver" output="screen" args='$(arg __enable_multi_robot_arg)'>
3739
<param name="rate" type="double" value="30.0"/>
3840
<param name="timeout" type="double" value="0.5"/>
3941
<remap from="cmd_vel" to="/stretch/cmd_vel" />

stretch_core/nodes/joint_trajectory_server.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ class JointTrajectoryAction:
1919

2020
def __init__(self, node):
2121
self.node = node
22-
self.server = actionlib.SimpleActionServer('/stretch_controller/follow_joint_trajectory',
22+
if self.node.robot_name==None:
23+
servername = '/stretch_controller/follow_joint_trajectory'
24+
else:
25+
servername = '/'+self.node.robot_name+'/follow_joint_trajectory'
26+
self.server = actionlib.SimpleActionServer(servername,
2327
FollowJointTrajectoryAction,
2428
execute_cb=self.execute_cb,
2529
auto_start=False)

stretch_core/nodes/stretch_driver

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
import yaml
44
import copy
5+
import argparse
56
import numpy as np
67
import threading
78
from rwlock import RWLock
89
import stretch_body.robot as rb
10+
import stretch_body.hello_utils as hu
911
from stretch_body.hello_utils import ThreadServiceExit
1012
import stretch_body
1113

@@ -34,7 +36,7 @@ from stretch_diagnostics import StretchDiagnostics
3436

3537
class StretchDriverNode:
3638

37-
def __init__(self):
39+
def __init__(self, robot_name = None):
3840
self.default_goal_timeout_s = 10.0
3941
self.default_goal_timeout_duration = rospy.Duration(self.default_goal_timeout_s)
4042

@@ -48,6 +50,8 @@ class StretchDriverNode:
4850
self.voltage_history = []
4951
self.charging_state_history = [BatteryState.POWER_SUPPLY_STATUS_UNKNOWN] * 10
5052
self.charging_state = BatteryState.POWER_SUPPLY_STATUS_UNKNOWN
53+
54+
self.robot_name = robot_name
5155

5256
###### MOBILE BASE VELOCITY METHODS #######
5357

@@ -538,7 +542,10 @@ class StretchDriverNode:
538542
self.odom_frame_id = 'odom'
539543
rospy.loginfo("{0} odom_frame_id = {1}".format(self.node_name, self.odom_frame_id))
540544

541-
self.joint_state_pub = rospy.Publisher('joint_states', JointState, queue_size=1)
545+
if self.robot_name==None:
546+
self.joint_state_pub = rospy.Publisher('joint_states', JointState, queue_size=1)
547+
else:
548+
self.joint_state_pub = rospy.Publisher('/'+self.robot_name+'joint_states', JointState, queue_size=1)
542549

543550
command_base_velocity_and_publish_joint_state_rate = rospy.Rate(self.joint_state_rate)
544551
self.last_twist_time = rospy.get_time()
@@ -594,5 +601,10 @@ class StretchDriverNode:
594601

595602

596603
if __name__ == '__main__':
597-
node = StretchDriverNode()
604+
parser = argparse.ArgumentParser()
605+
parser.add_argument('--enable_multi_robot', action='store_true', help='Turn on namespacing of topics/services/actions to the robots unique name, thereby allowing control of multiple robots simultaneously.')
606+
607+
args, unknown = parser.parse_known_args()
608+
robot_name = hu.get_fleet_id() if args.enable_multi_robot else None
609+
node = StretchDriverNode(robot_name)
598610
node.main()

0 commit comments

Comments
 (0)