Skip to content

Commit

Permalink
Merge pull request #2 from IOES-Lab/fuel-models
Browse files Browse the repository at this point in the history
Fuel model usage and migration to ROS 2 launch files
  • Loading branch information
rakeshv24 authored Jun 20, 2024
2 parents af720f4 + 8e4df54 commit 06b2c3a
Show file tree
Hide file tree
Showing 12 changed files with 473 additions and 0 deletions.
11 changes: 11 additions & 0 deletions dave_demos/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.8)
project(dave_demos)

find_package(ament_cmake REQUIRED)

install(
DIRECTORY launch
DESTINATION share/dave_demos
)

ament_package()
53 changes: 53 additions & 0 deletions dave_demos/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
## Examples

### 1. Launching a Dave Model using Fuel URI

To launch a Dave model directly from a Fuel URI, follow these steps:

1. Build and source the workspace:

```bash
colcon build && source install/setup.bash
```

2. Launch the model using the specified launch file:

```bash
ros2 launch dave_demos model_in_empty_world.launch.py model_name:='mossy_cinder_block'
```

This method simplifies the process by pulling the model directly from Fuel, ensuring you always have the latest version without needing to manage local files.

### 2. Launching a Dave Model using Downloaded Model Files

If you prefer to use model files downloaded from Fuel, proceed as follows:

1. Add a hook within the `dave_model_description` package to configure the necessary environment variables for Gazebo model lookup.

```bash
cd <path-to-dave_ws>/src/dave/dave_model_description
mkdir hooks && cd hooks
touch dave_model_description.dsv.in
echo "prepend-non-duplicate;GZ_SIM_RESOURCE_PATH;@CMAKE_INSTALL_PREFIX@/share/@PROJECT_NAME@" >> dave_model_description.dsv.in
```

2. Append the following line to the CMakeLists.txt file in the `dave_model_description` package:

```bash
ament_environment_hooks("${CMAKE_CURRENT_SOURCE_DIR}/hooks/${PROJECT_NAME}.dsv.in")
```

3. Build and source the workspace:

```bash
cd <path-to-dave_ws>
colcon build && source install/setup.bash
```

4. Launch the model using the provided launch file:

```bash
ros2 launch dave_demos model_in_empty_world.launch.py model_name:='nortek_dvl500_300'
```

This approach gives you more control over the models you use, allowing for offline use and customization. It's especially useful when working in environments with limited internet connectivity or when specific model versions are required.
82 changes: 82 additions & 0 deletions dave_demos/launch/model_in_empty_world.launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription
from launch.substitutions import (
LaunchConfiguration,
PathJoinSubstitution
)
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.conditions import IfCondition
from launch_ros.substitutions import FindPackageShare


def generate_launch_description():
use_sim = LaunchConfiguration("use_sim")
model_name = LaunchConfiguration("model_name")
gazebo_world_file = LaunchConfiguration("gazebo_world_file")

# Declare the launch arguments with default values
args = [
DeclareLaunchArgument(
"gazebo_world_file",
default_value="empty.sdf",
description="Gazebo world file to launch",
),
DeclareLaunchArgument(
"use_sim",
default_value="true",
description="Flag to indicate whether to use simulation",
),
DeclareLaunchArgument(
"model_name",
default_value="mossy_cinder_block",
description="Name of the model to load",
),
]

# Include the first launch file
gz_sim_launch = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
[
PathJoinSubstitution(
[
FindPackageShare("ros_gz_sim"),
"launch",
"gz_sim.launch.py",
]
)
]
),
launch_arguments=[
(
"gz_args",
[
"-r ",
gazebo_world_file,
],
),
],
condition=IfCondition(use_sim),
)

# Include the second launch file with model name
model_launch = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
[
PathJoinSubstitution(
[
FindPackageShare("dave_model_description"),
"launch",
"upload_model.launch.py",
]
)
]
),
launch_arguments={
"model_name": model_name,
"use_sim": use_sim,
}.items(),
)

include = [gz_sim_launch, model_launch]

return LaunchDescription(args + include)
18 changes: 18 additions & 0 deletions dave_demos/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">

<name>dave_demos</name>
<version>0.1.0</version>
<description> A package for demo launch files.</description>

<maintainer email="[email protected]">Rakesh Vivekanandan</maintainer>

<license>MIT</license>

<buildtool_depend>ament_cmake</buildtool_depend>

<export>
<build_type>ament_cmake</build_type>
</export>
</package>
13 changes: 13 additions & 0 deletions dave_model_description/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.8)
project(dave_model_description)

find_package(ament_cmake REQUIRED)

install(
DIRECTORY description launch meshes
DESTINATION share/dave_model_description
)

ament_environment_hooks("${CMAKE_CURRENT_SOURCE_DIR}/hooks/${PROJECT_NAME}.dsv.in")

ament_package()
10 changes: 10 additions & 0 deletions dave_model_description/description/mossy_cinder_block/model.sdf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" ?>
<sdf version="1.5">
<include>
<name>mossy_cinder_block</name>
<pose>0 0 0 0 0 0</pose>
<uri>
https://fuel.gazebosim.org/1.0/hmoyen/models/mossy_cinder_block
</uri>
</include>
</sdf>
97 changes: 97 additions & 0 deletions dave_model_description/description/nortek_dvl500_300/model.sdf
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?xml version="1.0"?>
<sdf version="1.6">
<model name="dvl500_300">
<link name="dvl500_base_link">
<pose>0 0 0 0 0 0</pose>
<inertial>
<pose>0 0 0 0 0 0</pose>
<mass>3.5</mass>
<inertia>
<ixx>0.0195872</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.0195872</iyy>
<iyz>0</iyz>
<izz>0.0151357</izz>
</inertia>
</inertial>
<velocity_decay/>
<gravity>1</gravity>
<velocity_decay/>
<!-- Removed sensor -->
<self_collide>0</self_collide>
<enable_wind>0</enable_wind>
<kinematic>0</kinematic>
<visual name="dvl500_base_link_visual">
<pose>0 0 0 0 0 3.14159</pose>
<geometry>
<mesh>
<scale>1 1 1</scale>
<!-- Mesh is actually for a Nortek DVL1000-4000m for now -->
<uri>model://meshes/nortek_dvl500_300/DVL500-300m.dae</uri>
</mesh>
</geometry>
<transparency>0</transparency>
<cast_shadows>1</cast_shadows>
</visual>
<collision name="dvl500_base_link_collision">
<laser_retro>0</laser_retro>
<max_contacts>10</max_contacts>
<pose>0 0 0 3.14159 0 0</pose>
<geometry>
<cylinder>
<radius>0.093</radius>
<length>0.203</length>
</cylinder>
</geometry>
<surface>
<friction>
<ode>
<mu>1</mu>
<mu2>1</mu2>
<fdir1>0 0 0</fdir1>
<slip1>0</slip1>
<slip2>0</slip2>
</ode>
<torsional>
<coefficient>1</coefficient>
<patch_radius>0</patch_radius>
<surface_radius>0</surface_radius>
<use_patch_radius>1</use_patch_radius>
<ode>
<slip>0</slip>
</ode>
</torsional>
</friction>
<bounce>
<restitution_coefficient>0</restitution_coefficient>
<threshold>1e+06</threshold>
</bounce>
<contact>
<collide_without_contact>0</collide_without_contact>
<collide_without_contact_bitmask>1</collide_without_contact_bitmask>
<collide_bitmask>1</collide_bitmask>
<ode>
<soft_cfm>0</soft_cfm>
<soft_erp>0.2</soft_erp>
<kp>1e+13</kp>
<kd>1</kd>
<max_vel>0.01</max_vel>
<min_depth>0</min_depth>
</ode>
<bullet>
<split_impulse>1</split_impulse>
<split_impulse_penetration_threshold>-0.01</split_impulse_penetration_threshold>
<soft_cfm>0</soft_cfm>
<soft_erp>0.2</soft_erp>
<kp>1e+13</kp>
<kd>1</kd>
</bullet>
</contact>
</surface>
</collision>
</link>
<static>0</static>
<allow_auto_disable>1</allow_auto_disable>
</model>
</sdf>
1 change: 1 addition & 0 deletions dave_model_description/hooks/dave_model_description.dsv.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
prepend-non-duplicate;GZ_SIM_RESOURCE_PATH;@CMAKE_INSTALL_PREFIX@/share/@PROJECT_NAME@
53 changes: 53 additions & 0 deletions dave_model_description/launch/upload_model.launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, RegisterEventHandler, LogInfo
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
from launch.conditions import IfCondition
from launch_ros.substitutions import FindPackageShare
from launch.event_handlers import OnProcessExit
from launch_ros.actions import Node


def generate_launch_description():
model_name = LaunchConfiguration("model_name")
use_sim = LaunchConfiguration("use_sim")

args = [
DeclareLaunchArgument(
"model_name",
default_value="model",
description="Name of the model to load",
),
DeclareLaunchArgument(
"use_sim",
default_value="true",
description="Flag to indicate whether to use simulation",
),
]

description_file = PathJoinSubstitution(
[
FindPackageShare("dave_model_description"),
"description",
model_name,
"model.sdf",
]
)

gz_spawner = Node(
package="ros_gz_sim",
executable="create",
arguments=["-name", model_name, "-file", description_file],
output="both",
condition=IfCondition(use_sim),
parameters=[{"use_sim_time": use_sim}],
)

nodes = [gz_spawner]

event_handlers = [
RegisterEventHandler(
OnProcessExit(target_action=gz_spawner, on_exit=LogInfo(msg="Model Uploaded"))
)
]

return LaunchDescription(args + nodes + event_handlers)
Loading

0 comments on commit 06b2c3a

Please sign in to comment.