Skip to content

Commit 9f9fe75

Browse files
committed
Backport #149: Add config directory
1 parent 9591b22 commit 9f9fe75

File tree

13 files changed

+321
-78
lines changed

13 files changed

+321
-78
lines changed

README.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,8 @@ ros2 launch rosbot_gazebo simulation.launch.py robot_model:=<rosbot/rosbot_xl>
9898

9999
| 🤖 | 🖥️ | Argument | Description <br/> **_Type:_** `Default` |
100100
| --- | --- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
101-
||| `components_config` | Specify file which contains components. These components will be included in URDF. Available options can be found in [husarion_components_description](https://github.com/husarion/husarion_components_description/blob/ros2/README.md#available-urdf-sensors) <br/> **_string_:** [`components.yaml`](rosbot_description/config/components.yaml) |
102-
||| `configuration` | Specify configuration packages. Currently only ROSbot XL has available packages. Packages: `basic`, `telepresence`, `autonomy`, `manipulation`, `manipulation_pro`. <br/> **_string:_** 'basic' |
103-
||| `controller_config` | Path to controller configuration file. <br/> **_string:_** [`{robot_model}/{mecanum/diff}_drive_controller.yaml`](rosbot_controller/config/) |
104-
||| `joy_config` | The file path to the configuration YAML file for the `teleop_twist_joy` node. <br/> **_string:_** [`joy.yaml`](rosbot_bringup/config/joy.yaml) |
101+
||| `config_dir` | Path to the common configuration directory. You can create such common configuration directory with `ros2 run rosbot_utils create_config_dir {directory}`. <br/> **_string:_** `""` |
102+
||| `configuration` | Specify configuration packages. Currently only ROSbot XL has available packages. Packages: `basic`, `telepresence`, `autonomy`, `manipulation`, `manipulation_pro`, `custom`. <br/> **_string:_** 'basic' |
105103
||| `joy_vel` | The topic name to which velocity commands will be published. <br/> **_string:_** `cmd_vel` |
106104
||| `mecanum` | Whether to use mecanum drive controller, otherwise use diff drive. <br/> **_bool:_** `False` |
107105
||| `namespace` | Add namespace to all launched nodes. <br/> **_string:_** `env(ROBOT_NAMESPACE)` |
@@ -111,7 +109,6 @@ ros2 launch rosbot_gazebo simulation.launch.py robot_model:=<rosbot/rosbot_xl>
111109
||| `port` | **ROSbot XL only.** UDP4 port for micro-ROS agent. <br/> **_string:_** `8888` |
112110
||| `serial_baudrate` | ROSbot only. Baud rate for serial communication. <br/> **_string:_** `576000` |
113111
||| `serial_port` | ROSbot only. Serial port for micro-ROS agent. <br/> **_string:_** `/dev/ttySERIAL` |
114-
||| `fastrtps_profiles` | Path to the Fast RTPS default profiles file for Micro-ROS agent for localhost only setup. <br/> **_string:_** [`microros_localhost_only.xml`](./rosbot_bringup/config/microros_localhost_only.xml) |
115112
||| `gz_gui` | Run simulation with specific GUI layout. <br/> **_string:_** [`teleop.config`](https://github.com/husarion/husarion_gz_worlds/blob/main/config/teleop.config) |
116113
||| `gz_headless_mode` | Run the simulation in headless mode. Useful when a GUI is not needed or to reduce the number of calculations. <br/> **_bool:_** `False` |
117114
||| `gz_log_level` | Adjust the level of console output. <br/> **_int:_** `1` (choices: `0`, `1`, `2`, `3`, `4`) |
@@ -125,8 +122,7 @@ ros2 launch rosbot_gazebo simulation.launch.py robot_model:=<rosbot/rosbot_xl>
125122
||| `yaw` | Initial robot 'yaw' orientation. <br/> **_float:_** `0.0` |
126123

127124
> [!TIP]
128-
>
129-
> To read the arguments for individual packages, add the `-s` flag to the `ros2 launch` command (e.g. `ros2 launch rosbot_bringup bringup.launch.py ​​-s`)
125+
> To read the arguments for individual launch files, add the `-s` flag to the `ros2 launch` command (e.g. `ros2 launch rosbot_bringup bringup.launch.py ​​-s`)
130126
131127
## 🕹️ Demo
132128

rosbot_bringup/launch/microros.launch.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
EnvironmentVariable,
2626
LaunchConfiguration,
2727
PathJoinSubstitution,
28+
PythonExpression,
2829
)
2930
from launch_ros.actions import Node
3031
from launch_ros.substitutions import FindPackageShare
@@ -39,12 +40,27 @@ def generate_microros_agent_node(context, *args, **kwargs):
3940
SetEnvironmentVariable(name="XRCE_DOMAIN_ID_OVERRIDE", value=ros_domain_id)
4041
)
4142

42-
fastrtps_profiles = LaunchConfiguration("fastrtps_profiles").perform(context)
43+
config_dir = LaunchConfiguration("config_dir").perform(context)
4344
port = LaunchConfiguration("port").perform(context)
4445
robot_model = LaunchConfiguration("robot_model").perform(context)
4546
serial_baudrate = LaunchConfiguration("serial_baudrate").perform(context)
4647
serial_port = LaunchConfiguration("serial_port").perform(context)
4748

49+
config_rosbot_bringup_dir = PythonExpression(
50+
[
51+
"'",
52+
config_dir,
53+
"/rosbot_bringup' if '",
54+
config_dir,
55+
"' else '",
56+
FindPackageShare("rosbot_bringup"),
57+
"'",
58+
]
59+
)
60+
fastrtps_profiles = PathJoinSubstitution(
61+
[config_rosbot_bringup_dir, "config", "microros_localhost_only.xml"]
62+
)
63+
4864
micoros_communication_args = {
4965
"rosbot": ["serial", "-b", serial_baudrate, "-D", serial_port],
5066
"rosbot_xl": ["udp4", "--port", port],
@@ -78,15 +94,10 @@ def generate_microros_agent_node(context, *args, **kwargs):
7894

7995

8096
def generate_launch_description():
81-
default_fastrtps_profiles = PathJoinSubstitution(
82-
[FindPackageShare("rosbot_bringup"), "config", "microros_localhost_only.xml"]
83-
)
84-
declare_fastrtps_profiles_arg = DeclareLaunchArgument(
85-
"fastrtps_profiles",
86-
default_value=default_fastrtps_profiles,
87-
description=(
88-
"Path to the Fast RTPS default profiles file for Micro-ROS agent for localhost only setup"
89-
),
97+
declare_config_dir_arg = DeclareLaunchArgument(
98+
"config_dir",
99+
default_value="",
100+
description="Path to the common configuration directory. You can create such common configuration directory with `ros2 run rosbot_utils create_config_dir {directory}`.",
90101
)
91102

92103
declare_port_arg = DeclareLaunchArgument(
@@ -116,7 +127,7 @@ def generate_launch_description():
116127

117128
return LaunchDescription(
118129
[
119-
declare_fastrtps_profiles_arg,
130+
declare_config_dir_arg,
120131
declare_port_arg,
121132
declare_robot_model_arg,
122133
declare_serial_baudrate_arg,

rosbot_controller/launch/controller.launch.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,25 @@
4040

4141

4242
def generate_launch_description():
43+
config_dir = LaunchConfiguration("config_dir")
4344
configuration = LaunchConfiguration("configuration")
44-
controller_config = LaunchConfiguration("controller_config")
4545
manipulator_serial_port = LaunchConfiguration("manipulator_serial_port")
4646
mecanum = LaunchConfiguration("mecanum")
4747
namespace = LaunchConfiguration("namespace")
4848
robot_model = LaunchConfiguration("robot_model")
4949
use_sim = LaunchConfiguration("use_sim", default="False")
5050

51+
config_search_path = PythonExpression(
52+
[
53+
"'",
54+
config_dir,
55+
"/rosbot_controller' if '",
56+
config_dir,
57+
"' else '",
58+
FindPackageShare("rosbot_controller"),
59+
"'",
60+
]
61+
)
5162
base_controller_prefix = PythonExpression(
5263
["'mecanum_drive' if ", mecanum, " else 'diff_drive'"]
5364
)
@@ -56,14 +67,14 @@ def generate_launch_description():
5667
controller_config_file = PythonExpression(
5768
["'", base_controller_prefix, "' + '_' + '", manipulator_prefix, "' + 'controller.yaml'"]
5869
)
59-
default_controller_config = PathJoinSubstitution(
60-
[FindPackageShare("rosbot_controller"), "config", robot_model, controller_config_file]
70+
controller_config = PathJoinSubstitution(
71+
[config_search_path, "config", robot_model, controller_config_file]
6172
)
6273

63-
declare_controller_config_arg = DeclareLaunchArgument(
64-
"controller_config",
65-
default_value=default_controller_config,
66-
description="Path to controller configuration file.",
74+
declare_config_dir_arg = DeclareLaunchArgument(
75+
"config_dir",
76+
default_value="",
77+
description="Path to the common configuration directory. You can create such common configuration directory with `ros2 run rosbot_utils create_config_dir {directory}`.",
6778
)
6879

6980
declare_configuration_arg = DeclareLaunchArgument(
@@ -72,7 +83,14 @@ def generate_launch_description():
7283
description=(
7384
"Specify configuration packages. Currently only ROSbot XL has available packages."
7485
),
75-
choices=["basic", "telepresence", "autonomy", "manipulation", "manipulation_pro"],
86+
choices=[
87+
"basic",
88+
"telepresence",
89+
"autonomy",
90+
"manipulation",
91+
"manipulation_pro",
92+
"custom",
93+
],
7694
)
7795

7896
default_manipulator_serial_port = find_device_port("0403", "6014", "/dev/ttyUSB0")
@@ -215,11 +233,11 @@ def check_if_log_is_fatal(event):
215233

216234
return LaunchDescription(
217235
[
236+
declare_config_dir_arg,
218237
declare_configuration_arg,
219238
declare_manipulator_serial_port_arg,
220239
declare_robot_model_arg,
221240
declare_mecanum_arg, # mecanum base on robot_model arg
222-
declare_controller_config_arg, # controler_config base on mecanum and robot_model arg
223241
load_urdf,
224242
control_node,
225243
delayed_controllers,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
components: []
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
components: []

rosbot_description/launch/load_urdf.launch.py

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17+
import os
18+
1719
import yaml
20+
from ament_index_python.packages import get_package_share_directory
1821
from launch import LaunchDescription
1922
from launch.actions import DeclareLaunchArgument, OpaqueFunction
2023
from launch.conditions import IfCondition
@@ -39,7 +42,7 @@ def contains_cam_component(yaml_fil):
3942

4043

4144
def launch_setup(context, *args, **kwargs):
42-
components_config = LaunchConfiguration("components_config").perform(context)
45+
config_dir = LaunchConfiguration("config_dir").perform(context)
4346
configuration = LaunchConfiguration("configuration").perform(context)
4447
controller_config = LaunchConfiguration("controller_config", default="").perform(context)
4548
manipulator_serial_port = LaunchConfiguration(
@@ -51,7 +54,17 @@ def launch_setup(context, *args, **kwargs):
5154
robot_model = LaunchConfiguration("robot_model").perform(context)
5255
use_sim = LaunchConfiguration("use_sim", default="False").perform(context)
5356

54-
if robot_model != "rosbot_xl" and configuration != "basic":
57+
config_rosbot_description_dir = (
58+
config_dir + "/rosbot_description"
59+
if config_dir
60+
else get_package_share_directory("rosbot_description")
61+
)
62+
components_file = f"{configuration}.yaml"
63+
components_config = os.path.join(
64+
config_rosbot_description_dir, "config", robot_model, components_file
65+
)
66+
67+
if robot_model != "rosbot_xl" and configuration not in ("basic", "custom"):
5568
raise ValueError(
5669
"Invalid configuration and robot model combination. Only 'rosbot_xl' has configuration options."
5770
)
@@ -112,19 +125,12 @@ def launch_setup(context, *args, **kwargs):
112125

113126

114127
def generate_launch_description():
115-
configuration = LaunchConfiguration("configuration")
116128
robot_model = LaunchConfiguration("robot_model")
117-
components_file = PythonExpression(["'", configuration, "' + '.yaml'"])
118-
default_components_config = PathJoinSubstitution(
119-
[FindPackageShare("rosbot_description"), "config", robot_model, components_file]
120-
)
121-
declare_components_config_arg = DeclareLaunchArgument(
122-
"components_config",
123-
default_value=default_components_config,
124-
description=(
125-
"Specify file which contains components. These components will be included in URDF. "
126-
"Available options can be found in [husarion_components_description](https://github.com/husarion/husarion_components_description/blob/jazzy/README.md#available-urdf-sensors)"
127-
),
129+
130+
declare_config_dir_arg = DeclareLaunchArgument(
131+
"config_dir",
132+
default_value="",
133+
description="Path to the common configuration directory. You can create such common configuration directory with `ros2 run rosbot_utils create_config_dir {directory}`.",
128134
)
129135

130136
declare_configuration_arg = DeclareLaunchArgument(
@@ -133,7 +139,14 @@ def generate_launch_description():
133139
description=(
134140
"Specify configuration packages. Currently only ROSbot XL has available packages"
135141
),
136-
choices=["basic", "telepresence", "autonomy", "manipulation", "manipulation_pro"],
142+
choices=[
143+
"basic",
144+
"telepresence",
145+
"autonomy",
146+
"manipulation",
147+
"manipulation_pro",
148+
"custom",
149+
],
137150
)
138151

139152
default_mecanum_value = PythonExpression(["'", robot_model, "' == 'rosbot_xl'"])
@@ -155,9 +168,9 @@ def generate_launch_description():
155168

156169
return LaunchDescription(
157170
[
171+
declare_config_dir_arg,
158172
declare_configuration_arg,
159173
declare_robot_model_arg,
160-
declare_components_config_arg, # depends on configuration and robot model
161174
declare_mecanum_arg, # mecanum base on robot_model arg
162175
publish_robot_description,
163176
]

rosbot_gazebo/launch/simulation.launch.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,25 @@
1616
from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription
1717
from launch.conditions import IfCondition
1818
from launch.launch_description_sources import PythonLaunchDescriptionSource
19-
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
19+
from launch.substitutions import (
20+
LaunchConfiguration,
21+
PathJoinSubstitution,
22+
PythonExpression,
23+
)
2024
from launch_ros.actions import Node, SetParameter, SetRemap
2125
from launch_ros.substitutions import FindPackageShare
2226

2327

2428
def generate_launch_description():
29+
config_dir = LaunchConfiguration("config_dir")
2530
rviz = LaunchConfiguration("rviz")
31+
32+
declare_config_dir_arg = DeclareLaunchArgument(
33+
"config_dir",
34+
default_value="",
35+
description="Path to the common configuration directory. You can create such common configuration directory with `ros2 run rosbot_utils create_config_dir {directory}`.",
36+
)
37+
2638
declare_rviz_arg = DeclareLaunchArgument(
2739
"rviz",
2840
default_value="True",
@@ -39,9 +51,19 @@ def generate_launch_description():
3951
launch_arguments={"gz_log_level": "1"}.items(),
4052
)
4153

42-
gz_bridge_config = PathJoinSubstitution(
43-
[FindPackageShare("rosbot_gazebo"), "config", "gz_bridge.yaml"]
54+
config_rosbot_gazebo_dir = PythonExpression(
55+
[
56+
"'",
57+
config_dir,
58+
"/rosbot_gazebo' if '",
59+
config_dir,
60+
"' else '",
61+
FindPackageShare("rosbot_gazebo"),
62+
"'",
63+
]
4464
)
65+
66+
gz_bridge_config = PathJoinSubstitution([config_rosbot_gazebo_dir, "config", "gz_bridge.yaml"])
4567
gz_bridge = Node(
4668
package="ros_gz_bridge",
4769
executable="parameter_bridge",
@@ -77,6 +99,7 @@ def generate_launch_description():
7799

78100
return LaunchDescription(
79101
[
102+
declare_config_dir_arg,
80103
declare_rviz_arg,
81104
SetRemap("/diagnostics", "diagnostics"),
82105
SetRemap("/tf", "tf"),

0 commit comments

Comments
 (0)