Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,8 @@ ros2 launch rosbot_gazebo simulation.launch.py robot_model:=<rosbot/rosbot_xl>

| 🤖 | 🖥️ | Argument | Description <br/> **_Type:_** `Default` |
| --- | --- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ✅ | ✅ | `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) |
| ✅ | ✅ | `configuration` | Specify configuration packages. Currently only ROSbot XL has available packages. Packages: `basic`, `telepresence`, `autonomy`, `manipulation`, `manipulation_pro`. <br/> **_string:_** 'basic' |
| ✅ | ✅ | `controller_config` | Path to controller configuration file. <br/> **_string:_** [`{robot_model}/{mecanum/diff}_drive_controller.yaml`](rosbot_controller/config/) |
| ✅ | ✅ | `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) |
| ✅ | ✅ | `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:_** `""` |
| ✅ | ✅ | `configuration` | Specify configuration packages. Currently only ROSbot XL has available packages. Packages: `basic`, `telepresence`, `autonomy`, `manipulation`, `manipulation_pro`, `custom`. <br/> **_string:_** 'basic' |
| ✅ | ✅ | `joy_vel` | The topic name to which velocity commands will be published. <br/> **_string:_** `cmd_vel` |
| ✅ | ✅ | `mecanum` | Whether to use mecanum drive controller, otherwise use diff drive. <br/> **_bool:_** `False` |
| ✅ | ✅ | `namespace` | Add namespace to all launched nodes. <br/> **_string:_** `env(ROBOT_NAMESPACE)` |
Expand All @@ -111,7 +109,6 @@ ros2 launch rosbot_gazebo simulation.launch.py robot_model:=<rosbot/rosbot_xl>
| ✅ | ❌ | `port` | **ROSbot XL only.** UDP4 port for micro-ROS agent. <br/> **_string:_** `8888` |
| ✅ | ❌ | `serial_baudrate` | ROSbot only. Baud rate for serial communication. <br/> **_string:_** `576000` |
| ✅ | ❌ | `serial_port` | ROSbot only. Serial port for micro-ROS agent. <br/> **_string:_** `/dev/ttySERIAL` |
| ✅ | ❌ | `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) |
| ❌ | ✅ | `gz_gui` | Run simulation with specific GUI layout. <br/> **_string:_** [`teleop.config`](https://github.com/husarion/husarion_gz_worlds/blob/main/config/teleop.config) |
| ❌ | ✅ | `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` |
| ❌ | ✅ | `gz_log_level` | Adjust the level of console output. <br/> **_int:_** `1` (choices: `0`, `1`, `2`, `3`, `4`) |
Expand All @@ -125,8 +122,7 @@ ros2 launch rosbot_gazebo simulation.launch.py robot_model:=<rosbot/rosbot_xl>
| ❌ | ✅ | `yaw` | Initial robot 'yaw' orientation. <br/> **_float:_** `0.0` |

> [!TIP]
>
> 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`)
> 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`)

## 🕹️ Demo

Expand Down
33 changes: 22 additions & 11 deletions rosbot_bringup/launch/microros.launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
EnvironmentVariable,
LaunchConfiguration,
PathJoinSubstitution,
PythonExpression,
)
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare
Expand All @@ -39,12 +40,27 @@ def generate_microros_agent_node(context, *args, **kwargs):
SetEnvironmentVariable(name="XRCE_DOMAIN_ID_OVERRIDE", value=ros_domain_id)
)

fastrtps_profiles = LaunchConfiguration("fastrtps_profiles").perform(context)
config_dir = LaunchConfiguration("config_dir").perform(context)
port = LaunchConfiguration("port").perform(context)
robot_model = LaunchConfiguration("robot_model").perform(context)
serial_baudrate = LaunchConfiguration("serial_baudrate").perform(context)
serial_port = LaunchConfiguration("serial_port").perform(context)

config_rosbot_bringup_dir = PythonExpression(
[
"'",
config_dir,
"/rosbot_bringup' if '",
config_dir,
"' else '",
FindPackageShare("rosbot_bringup"),
"'",
]
)
fastrtps_profiles = PathJoinSubstitution(
[config_rosbot_bringup_dir, "config", "microros_localhost_only.xml"]
)

micoros_communication_args = {
"rosbot": ["serial", "-b", serial_baudrate, "-D", serial_port],
"rosbot_xl": ["udp4", "--port", port],
Expand Down Expand Up @@ -78,15 +94,10 @@ def generate_microros_agent_node(context, *args, **kwargs):


def generate_launch_description():
default_fastrtps_profiles = PathJoinSubstitution(
[FindPackageShare("rosbot_bringup"), "config", "microros_localhost_only.xml"]
)
declare_fastrtps_profiles_arg = DeclareLaunchArgument(
"fastrtps_profiles",
default_value=default_fastrtps_profiles,
description=(
"Path to the Fast RTPS default profiles file for Micro-ROS agent for localhost only setup"
),
declare_config_dir_arg = DeclareLaunchArgument(
"config_dir",
default_value="",
description="Path to the common configuration directory. You can create such common configuration directory with `ros2 run rosbot_utils create_config_dir {directory}`.",
)

declare_port_arg = DeclareLaunchArgument(
Expand Down Expand Up @@ -116,7 +127,7 @@ def generate_launch_description():

return LaunchDescription(
[
declare_fastrtps_profiles_arg,
declare_config_dir_arg,
declare_port_arg,
declare_robot_model_arg,
declare_serial_baudrate_arg,
Expand Down
36 changes: 27 additions & 9 deletions rosbot_controller/launch/controller.launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,25 @@


def generate_launch_description():
config_dir = LaunchConfiguration("config_dir")
configuration = LaunchConfiguration("configuration")
controller_config = LaunchConfiguration("controller_config")
manipulator_serial_port = LaunchConfiguration("manipulator_serial_port")
mecanum = LaunchConfiguration("mecanum")
namespace = LaunchConfiguration("namespace")
robot_model = LaunchConfiguration("robot_model")
use_sim = LaunchConfiguration("use_sim", default="False")

config_search_path = PythonExpression(
[
"'",
config_dir,
"/rosbot_controller' if '",
config_dir,
"' else '",
FindPackageShare("rosbot_controller"),
"'",
]
)
base_controller_prefix = PythonExpression(
["'mecanum_drive' if ", mecanum, " else 'diff_drive'"]
)
Expand All @@ -56,14 +67,14 @@ def generate_launch_description():
controller_config_file = PythonExpression(
["'", base_controller_prefix, "' + '_' + '", manipulator_prefix, "' + 'controller.yaml'"]
)
default_controller_config = PathJoinSubstitution(
[FindPackageShare("rosbot_controller"), "config", robot_model, controller_config_file]
controller_config = PathJoinSubstitution(
[config_search_path, "config", robot_model, controller_config_file]
)

declare_controller_config_arg = DeclareLaunchArgument(
"controller_config",
default_value=default_controller_config,
description="Path to controller configuration file.",
declare_config_dir_arg = DeclareLaunchArgument(
"config_dir",
default_value="",
description="Path to the common configuration directory. You can create such common configuration directory with `ros2 run rosbot_utils create_config_dir {directory}`.",
)

declare_configuration_arg = DeclareLaunchArgument(
Expand All @@ -72,7 +83,14 @@ def generate_launch_description():
description=(
"Specify configuration packages. Currently only ROSbot XL has available packages."
),
choices=["basic", "telepresence", "autonomy", "manipulation", "manipulation_pro"],
choices=[
"basic",
"telepresence",
"autonomy",
"manipulation",
"manipulation_pro",
"custom",
],
)

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

return LaunchDescription(
[
declare_config_dir_arg,
declare_configuration_arg,
declare_manipulator_serial_port_arg,
declare_robot_model_arg,
declare_mecanum_arg, # mecanum base on robot_model arg
declare_controller_config_arg, # controler_config base on mecanum and robot_model arg
load_urdf,
control_node,
delayed_controllers,
Expand Down
2 changes: 2 additions & 0 deletions rosbot_description/config/rosbot/custom.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
components: []
2 changes: 2 additions & 0 deletions rosbot_description/config/rosbot_xl/custom.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
components: []
45 changes: 29 additions & 16 deletions rosbot_description/launch/load_urdf.launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import os

import yaml
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, OpaqueFunction
from launch.conditions import IfCondition
Expand All @@ -39,7 +42,7 @@ def contains_cam_component(yaml_fil):


def launch_setup(context, *args, **kwargs):
components_config = LaunchConfiguration("components_config").perform(context)
config_dir = LaunchConfiguration("config_dir").perform(context)
configuration = LaunchConfiguration("configuration").perform(context)
controller_config = LaunchConfiguration("controller_config", default="").perform(context)
manipulator_serial_port = LaunchConfiguration(
Expand All @@ -51,7 +54,17 @@ def launch_setup(context, *args, **kwargs):
robot_model = LaunchConfiguration("robot_model").perform(context)
use_sim = LaunchConfiguration("use_sim", default="False").perform(context)

if robot_model != "rosbot_xl" and configuration != "basic":
config_rosbot_description_dir = (
config_dir + "/rosbot_description"
if config_dir
else get_package_share_directory("rosbot_description")
)
components_file = f"{configuration}.yaml"
components_config = os.path.join(
config_rosbot_description_dir, "config", robot_model, components_file
)

if robot_model != "rosbot_xl" and configuration not in ("basic", "custom"):
raise ValueError(
"Invalid configuration and robot model combination. Only 'rosbot_xl' has configuration options."
)
Expand Down Expand Up @@ -112,19 +125,12 @@ def launch_setup(context, *args, **kwargs):


def generate_launch_description():
configuration = LaunchConfiguration("configuration")
robot_model = LaunchConfiguration("robot_model")
components_file = PythonExpression(["'", configuration, "' + '.yaml'"])
default_components_config = PathJoinSubstitution(
[FindPackageShare("rosbot_description"), "config", robot_model, components_file]
)
declare_components_config_arg = DeclareLaunchArgument(
"components_config",
default_value=default_components_config,
description=(
"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/jazzy/README.md#available-urdf-sensors)"
),

declare_config_dir_arg = DeclareLaunchArgument(
"config_dir",
default_value="",
description="Path to the common configuration directory. You can create such common configuration directory with `ros2 run rosbot_utils create_config_dir {directory}`.",
)

declare_configuration_arg = DeclareLaunchArgument(
Expand All @@ -133,7 +139,14 @@ def generate_launch_description():
description=(
"Specify configuration packages. Currently only ROSbot XL has available packages"
),
choices=["basic", "telepresence", "autonomy", "manipulation", "manipulation_pro"],
choices=[
"basic",
"telepresence",
"autonomy",
"manipulation",
"manipulation_pro",
"custom",
],
)

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

return LaunchDescription(
[
declare_config_dir_arg,
declare_configuration_arg,
declare_robot_model_arg,
declare_components_config_arg, # depends on configuration and robot model
declare_mecanum_arg, # mecanum base on robot_model arg
publish_robot_description,
]
Expand Down
29 changes: 26 additions & 3 deletions rosbot_gazebo/launch/simulation.launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,25 @@
from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription
from launch.conditions import IfCondition
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
from launch.substitutions import (
LaunchConfiguration,
PathJoinSubstitution,
PythonExpression,
)
from launch_ros.actions import Node, SetParameter, SetRemap
from launch_ros.substitutions import FindPackageShare


def generate_launch_description():
config_dir = LaunchConfiguration("config_dir")
rviz = LaunchConfiguration("rviz")

declare_config_dir_arg = DeclareLaunchArgument(
"config_dir",
default_value="",
description="Path to the common configuration directory. You can create such common configuration directory with `ros2 run rosbot_utils create_config_dir {directory}`.",
)

declare_rviz_arg = DeclareLaunchArgument(
"rviz",
default_value="True",
Expand All @@ -39,9 +51,19 @@ def generate_launch_description():
launch_arguments={"gz_log_level": "1"}.items(),
)

gz_bridge_config = PathJoinSubstitution(
[FindPackageShare("rosbot_gazebo"), "config", "gz_bridge.yaml"]
config_rosbot_gazebo_dir = PythonExpression(
[
"'",
config_dir,
"/rosbot_gazebo' if '",
config_dir,
"' else '",
FindPackageShare("rosbot_gazebo"),
"'",
]
)

gz_bridge_config = PathJoinSubstitution([config_rosbot_gazebo_dir, "config", "gz_bridge.yaml"])
gz_bridge = Node(
package="ros_gz_bridge",
executable="parameter_bridge",
Expand Down Expand Up @@ -77,6 +99,7 @@ def generate_launch_description():

return LaunchDescription(
[
declare_config_dir_arg,
declare_rviz_arg,
SetRemap("/diagnostics", "diagnostics"),
SetRemap("/tf", "tf"),
Expand Down
Loading
Loading