Skip to content

Commit 725279f

Browse files
committed
Pull request #206: fix: The docker build was missing the mobile_sensor deps
Merge in MOCTRL/franka_ros2 from fix-missed-mobile-sensor-deps to jazzy * commit '57bc9031361b4dfaa1daff053c34568a1ebcf7ac': docs: Added docu link to the 'mobile_sensors' package add: docu for franka_mobile_sensors package fix: franka_mobile_sensors formatting and linting issues fix: The docker build was missing the mobile_sensor deps
2 parents 2725795 + 57bc903 commit 725279f

16 files changed

Lines changed: 330 additions & 267 deletions

dependency.repos

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ repositories:
1111
type: git
1212
url: https://github.com/ros-controls/gz_ros2_control.git
1313
version: jazzy
14+
olvx_descriptions_module:
15+
type: git
16+
url: https://github.com/olive-robotics/olvx_descriptions_module.git
17+
version: main

docs/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ franka_ros2
1010
../franka_semantic_components/doc/index
1111
../franka_gripper/doc/index
1212
../franka_robot_state_broadcaster/doc/index
13+
../franka_mobile_sensors/doc/index
1314
../franka_fr3_moveit_config/doc/index
1415
../franka_gazebo_bringup/doc/index
1516
../franka_msgs/doc/index
1617
../franka_ros2/doc/compatibility_matrix
17-
../franka_selfcollision/doc/index
18+
../franka_selfcollision/doc/index

franka_mobile_sensors/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ project(franka_mobile_sensors)
44
find_package(ament_cmake REQUIRED)
55

66
install(
7-
DIRECTORY launch config rviz robots
7+
DIRECTORY launch config rviz robots doc
88
DESTINATION share/${PROJECT_NAME}
99
)
1010

franka_mobile_sensors/COLCON_IGNORE

Lines changed: 0 additions & 2 deletions
This file was deleted.

franka_mobile_sensors/README.md

Lines changed: 0 additions & 63 deletions
This file was deleted.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
franka_mobile_sensors
2+
=====================
3+
4+
Package Overview
5+
----------------
6+
7+
This package contains launch files and run-time configurations for using sensors on Franka Robotics mobile research robots.
8+
It provides integration for:
9+
10+
* **RealSense Cameras** - Intel RealSense depth cameras (D455)
11+
* **SICK Safety Scanners** - SICK nanoScan3 safety lidars
12+
* **Olive Robotics IMU** - Olive Robotics olixSense X1 IMU
13+
14+
The package handles sensor configuration, driver launching, and RViz visualization for the complete sensor suite.
15+
16+
Usage
17+
-----
18+
19+
Launch the complete sensor suite with::
20+
21+
ros2 launch franka_mobile_sensors franka_mobile_sensors.launch.py \
22+
robot_type:=<robot_type> \
23+
config_file:=<config_name>
24+
25+
Launch Arguments
26+
^^^^^^^^^^^^^^^^
27+
28+
* ``start_cameras`` (default: ``true``) - Start RealSense camera drivers
29+
* ``start_lidars`` (default: ``true``) - Start SICK safety scanner drivers
30+
* ``start_rviz`` (default: ``true``) - Start RViz visualization
31+
* ``robot_type`` (default: ``tmrv0_2``) - ID of the robot type for visualization
32+
* ``config_file`` (default: ``default_sensor_suite``) - Sensor suite configuration (without .yaml extension)
33+
34+
Configuration
35+
-------------
36+
37+
Sensor Suite Configuration
38+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
39+
40+
The main sensor suite is configured in:
41+
42+
* ``config/default_sensor_suite.yaml`` - Defines which sensors are used
43+
44+
This file specifies:
45+
46+
* List of cameras with their device profiles
47+
* List of lidars with their device profiles
48+
* Network configurations
49+
* Sensor placement and mounting parameters
50+
51+
Device-Specific Parameters
52+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
53+
54+
Individual device parameters are configured in device profile files:
55+
56+
**Cameras:**
57+
58+
* ``config/cameras/franka_mobile_d455.yaml`` - RealSense D455 parameters
59+
60+
**Lidars:**
61+
62+
* ``config/lidars/sick_nanoscan3.yaml`` - SICK nanoScan3 parameters
63+
64+
Custom Configurations
65+
^^^^^^^^^^^^^^^^^^^^^
66+
67+
To create a custom configuration:
68+
69+
1. Copy ``config/default_sensor_suite.yaml`` to ``config/my_custom_suite.yaml``
70+
2. Modify camera/lidar lists and reference existing or new device profiles
71+
3. Launch with: ``config_file:=my_custom_suite``
72+
73+
Example
74+
-------
75+
76+
To launch only cameras without lidars and RViz::
77+
78+
ros2 launch franka_mobile_sensors franka_mobile_sensors.launch.py \
79+
start_cameras:=true \
80+
start_lidars:=false \
81+
start_rviz:=false
82+
83+
To use a custom sensor configuration::
84+
85+
ros2 launch franka_mobile_sensors franka_mobile_sensors.launch.py \
86+
config_file:=my_custom_suite \
87+
robot_type:=tmrv0_2

franka_mobile_sensors/launch/cameras/camera_configs.py

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,87 +12,102 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import sys
16-
from pathlib import Path
1715
from dataclasses import dataclass, field
18-
from typing import List, Dict
16+
from pathlib import Path
17+
import sys
18+
from typing import Dict, List
1919

2020
# Add utils to path for shared utilities
2121
current_dir = Path(__file__).parent
2222
sys.path.append(str(current_dir.parent / 'utils'))
23-
from config_loader import load_yaml_config
23+
24+
from config_loader import load_yaml_config # noqa: E402
2425

2526

2627
@dataclass(frozen=True)
2728
class CameraConfig:
2829
"""Configuration for a single camera."""
30+
2931
name: str
3032
namespace: str
31-
device_profile: str
32-
serial_number: str = None
33-
usb_port: str = None
33+
device_profile: str
34+
serial_number: str = None
35+
usb_port: str = None
3436

3537
@property
3638
def node_name(self) -> str:
37-
return f"{self.name}_node"
39+
return f'{self.name}_node'
3840

3941
@classmethod
4042
def from_dict(cls, data: Dict) -> 'CameraConfig':
4143
return cls(
4244
name=data['name'],
4345
namespace=data['namespace'],
4446
device_profile=data['device_profile'],
45-
serial_number=data.get('serial_number'),
46-
usb_port=data.get('usb_port'),
47+
serial_number=data.get('serial_number'),
48+
usb_port=data.get('usb_port'),
4749
)
48-
50+
4951
def load_camera_parameters(self) -> Dict:
50-
"""Load camera-specific parameters from the device profile file.
51-
52-
Returns:
53-
Dictionary containing camera-specific parameters
52+
"""
53+
Load camera-specific parameters from the device profile file.
54+
55+
Returns
56+
-------
57+
dict
58+
Dictionary containing camera-specific parameters.
59+
5460
"""
5561
return load_yaml_config(self.device_profile, subdirectory='cameras')
5662

5763

5864
@dataclass(frozen=True)
5965
class CameraSuite:
6066
"""Configuration for all cameras."""
67+
6168
name: str
6269
description: str
6370
cameras: List[CameraConfig] = field(default_factory=list)
64-
71+
6572
def __post_init__(self):
6673
"""Validate camera configuration after initialization."""
6774
camera_names = [cam.name for cam in self.cameras]
68-
serial_numbers = [cam.serial_number for cam in self.cameras if cam.serial_number is not None]
69-
usb_ports = [cam.usb_port for cam in self.cameras if cam.usb_port is not None]
70-
75+
serial_numbers = [
76+
cam.serial_number for cam in self.cameras if cam.serial_number is not None]
77+
usb_ports = [
78+
cam.usb_port for cam in self.cameras if cam.usb_port is not None]
79+
7180
if len(set(camera_names)) != len(camera_names):
72-
raise ValueError("Camera names must be unique")
81+
raise ValueError('Camera names must be unique')
7382
if len(set(serial_numbers)) != len(serial_numbers):
74-
raise ValueError("Camera serial numbers must be unique")
83+
raise ValueError('Camera serial numbers must be unique')
7584
if len(set(usb_ports)) != len(usb_ports):
76-
raise ValueError("Camera USB ports must be unique")
85+
raise ValueError('Camera USB ports must be unique')
7786

7887
@classmethod
7988
def from_dict(cls, data: Dict) -> 'CameraSuite':
80-
cameras = [CameraConfig.from_dict(cam_data) for cam_data in data['cameras']]
89+
cameras = [CameraConfig.from_dict(cam_data)
90+
for cam_data in data['cameras']]
8191
return cls(
8292
name=data['name'],
8393
description=data['description'],
84-
cameras=cameras
85-
)
94+
cameras=cameras)
8695

8796

8897
def load_camera_suite_from_yaml(config_name: str) -> CameraSuite:
89-
"""Load camera suite configuration from YAML file.
90-
91-
Args:
92-
config_name: Name of the config file (without .yaml extension)
93-
94-
Returns:
95-
CameraSuite object loaded from the YAML file
98+
"""
99+
Load camera suite configuration from YAML file.
100+
101+
Parameters
102+
----------
103+
config_name : str
104+
Name of the config file (without .yaml extension)
105+
106+
Returns
107+
-------
108+
CameraSuite
109+
CameraSuite object loaded from the YAML file.
110+
96111
"""
97112
config_data = load_yaml_config(config_name)
98-
return CameraSuite.from_dict(config_data)
113+
return CameraSuite.from_dict(config_data)

0 commit comments

Comments
 (0)