diff --git a/CMakeLists.txt b/CMakeLists.txt index 194330a..1a3c202 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,4 +112,27 @@ install(DIRECTORY # Scripts Block [END] # ####################### +######################## +# Launch Block [BEGIN] # +# vvvvvvvvvvvvvvvvvvvv # +# According to https://github.com/SmartArmStack/sas_robot_driver/blob/ros2/CMakeLists.txt +install(DIRECTORY + launch + DESTINATION share/${PROJECT_NAME}/ +) +# ^^^^^^^^^^^^^^^^^^ # +# Launch Block [END] # +###################### + +######################### +# Config Block [BEGIN] # +# vvvvvvvvvvvvvvvvvvvvv # +install(DIRECTORY + config + DESTINATION share/${PROJECT_NAME}/ +) +# ^^^^^^^^^^^^^^^^^^^ # +# Config Block [END] # +####################### + ament_package() diff --git a/README.md b/README.md index efa2df3..d9ce192 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,32 @@ - `src/` — library and pybind11 bindings. - `sas_force_sensor/` — Python package (thin wrapper around the pybind11 module). - `scripts/` — Python example script. +- `launch/` — example launch file for the sinusoidal force sensor node. +- `config/` — example parameter configuration file. + +## ROS 2 Nodes & Parameters + +The package is primarily a library. It also provides one example node. + +### Node: `sinusoidal_force_sensor` + +| Property | Value | +|---|---| +| **Executable** | `sinusoidal_force_sensor` | +| **ROS node name** | `sinusoidal_force_sensor` (set by the `name` launch argument of `sinusoidal_force_sensor_launch.py`) | +| **Description** | Example node that publishes a sinusoidal force/torque wrench on `/get/wrench` via `ForceSensorServer`. | + +#### Parameters + +The node currently declares **no ROS parameters** — the amplitude, frequency, and tick rate are hardcoded constants in `src/examples/sinusoidal_force_sensor.cpp`. + +#### Sample launch + +```console +ros2 launch sas_force_sensor sinusoidal_force_sensor_launch.py +``` + +The launch file loads the (currently empty) parameter block from `config/config.yaml` (override with `config_file:=/path/to/config.yaml`) so the node follows the standard SmartArmStack config-file pattern. ## Client–Server pair diff --git a/config/config.yaml b/config/config.yaml new file mode 100644 index 0000000..e918b15 --- /dev/null +++ b/config/config.yaml @@ -0,0 +1,11 @@ +# Parameters for the sas_force_sensor nodes. +# +# Each top-level block is keyed by the ROS node name and is loaded by the +# corresponding launch file via its `config_file` argument. + +# sinusoidal_force_sensor (example node) +sinusoidal_force_sensor: + ros__parameters: {} + # The example sinusoidal force sensor declares no ROS parameters today. + # This block is kept so the node can be configured through the standard + # SmartArmStack config-file pattern once parameters are introduced. diff --git a/launch/sinusoidal_force_sensor_launch.py b/launch/sinusoidal_force_sensor_launch.py new file mode 100644 index 0000000..faeac65 --- /dev/null +++ b/launch/sinusoidal_force_sensor_launch.py @@ -0,0 +1,34 @@ +import os.path + +from ament_index_python.packages import get_package_share_directory +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.substitutions import LaunchConfiguration +from launch_ros.actions import Node + + +def generate_launch_description(): + """Launch the example sinusoidal force sensor node. + + Parameters are loaded from a YAML configuration file. Pass a different + file with ``config_file:=/path/to/config.yaml``. + """ + name = LaunchConfiguration('name') + config_file = LaunchConfiguration('config_file') + + return LaunchDescription([ + DeclareLaunchArgument( + 'name', + default_value='sinusoidal_force_sensor' + ), + DeclareLaunchArgument( + 'config_file', + default_value=os.path.join(get_package_share_directory('sas_force_sensor'), 'config', 'config.yaml') + ), + Node( + package='sas_force_sensor', + executable='sinusoidal_force_sensor', + name=name, + parameters=[config_file] + ) + ])