Skip to content

Commit

Permalink
add mock hardware components and namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
Serafadam committed Jan 3, 2024
1 parent 710c5f1 commit ddfa241
Show file tree
Hide file tree
Showing 15 changed files with 322 additions and 67 deletions.
7 changes: 4 additions & 3 deletions rae_description/launch/rsp.launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def launch_setup(context, *args, **kwargs):
package='robot_state_publisher',
executable='robot_state_publisher',
name='robot_state_publisher',
namespace=LaunchConfiguration('namespace'),
parameters=[{
'robot_description': Command(['xacro ', xacro_path, ' sim_mode:=', use_sim_time]),
'use_sim_time': use_sim_time
Expand All @@ -40,9 +41,9 @@ def generate_launch_description():
description='Use sim time'
),
DeclareLaunchArgument(
'use_sim_time',
default_value='false',
description='Use sim time'
'namespace',
default_value='',
description='Namespace'
),
DeclareLaunchArgument(
'run_container',
Expand Down
13 changes: 13 additions & 0 deletions rae_hw/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,18 @@ install(
DESTINATION include
)


ament_python_install_package(${PROJECT_NAME})
# Install Python executables
install(
PROGRAMS
scripts/mock_battery.py
scripts/mock_lcd.py
scripts/mock_leds.py
scripts/mock_mic.py
scripts/mock_speakers.py
scripts/mock_wheels.py
DESTINATION lib/${PROJECT_NAME}
)
ament_package()

46 changes: 29 additions & 17 deletions rae_hw/launch/control.launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,47 +16,53 @@ def launch_setup(context, *args, **kwargs):
'rae_description'), 'urdf', 'rae.urdf.xacro')
rae_description_config = xacro.process_file(rae_description_path)
robot_description = {'robot_description': rae_description_config.toxml()}
controller = os.path.join(get_package_share_directory(
'rae_hw'), 'config', 'controller.yaml')
controller_params = LaunchConfiguration('controller_params_file').perform(context)
run_container = LaunchConfiguration('run_container', default='true')
enable_battery_status = LaunchConfiguration('enable_battery_status', default='true')
enable_localization = LaunchConfiguration('enable_localization', default='true')

enable_localization = LaunchConfiguration(
'enable_localization', default='true')
return [
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(get_package_share_directory('rae_description'), 'launch', 'rsp.launch.py')),
launch_arguments={'sim': 'false'}.items()
launch_arguments={'sim': 'false',
'namespace': LaunchConfiguration('namespace'),
}.items()
),
Node(
condition=IfCondition(enable_localization),
package='robot_localization',
executable='ekf_node',
name='ekf_filter_node',
namespace=LaunchConfiguration('namespace'),
output='screen',
parameters=[os.path.join(get_package_share_directory(
'rae_hw'), 'config', 'ekf.yaml')],
),
Node(
package='imu_complementary_filter',
executable='complementary_filter_node',
name='complementary_filter_gain_node',
output='screen',
parameters=[
package='imu_complementary_filter',
executable='complementary_filter_node',
name='complementary_filter_gain_node',
namespace=LaunchConfiguration('namespace'),
output='screen',
parameters=[
{'do_bias_estimation': True},
{'do_adaptive_gain': True},
{'orientation_stddev': 0.001},
{'use_mag': False},
{'gain_acc': 0.04},
{'gain_mag': 0.01},
],
remappings=[
('/imu/data_raw', '/rae/imu/data'),
]
],
remappings=[
('imu/data_raw', '/rae/imu/data'),
]
),
Node(
package='controller_manager',
executable='ros2_control_node',
parameters=[robot_description, controller],
name='controller_manager',
namespace=LaunchConfiguration('namespace'),
parameters=[robot_description, controller_params],
remappings=[('/diff_controller/cmd_vel_unstamped', 'cmd_vel')],
output={
'stdout': 'screen',
Expand All @@ -66,31 +72,37 @@ def launch_setup(context, *args, **kwargs):

Node(
package='controller_manager',
namespace=LaunchConfiguration('namespace'),
executable='spawner',
arguments=['diff_controller', '-c', '/controller_manager'],
),

Node(
package='controller_manager',
executable='spawner',
namespace=LaunchConfiguration('namespace'),
arguments=['joint_state_broadcaster',
'--controller-manager', '/controller_manager'],
),
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(get_package_share_directory('rae_hw'), 'launch', 'peripherals.launch.py')),
launch_arguments={'run_container': run_container,
'enable_battery_status': enable_battery_status}.items()
'namespace': LaunchConfiguration('namespace'),
}.items()
),
]


def generate_launch_description():
declared_arguments = [
DeclareLaunchArgument('name', default_value='rae'),
DeclareLaunchArgument('namespace', default_value=''),
DeclareLaunchArgument('run_container', default_value='true'),
DeclareLaunchArgument('enable_battery_status', default_value='true'),
DeclareLaunchArgument('enable_localization', default_value='true')
DeclareLaunchArgument('enable_localization', default_value='true'),
DeclareLaunchArgument('controller_params_file', default_value=os.path.join(get_package_share_directory(
'rae_hw'), 'config', 'controller.yaml')),
]

return LaunchDescription(declared_arguments + [OpaqueFunction(function=launch_setup)])
75 changes: 75 additions & 0 deletions rae_hw/launch/control_mock.launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import os

from ament_index_python.packages import get_package_share_directory

from launch import LaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.actions import IncludeLaunchDescription, OpaqueFunction, DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch.conditions import IfCondition
from launch_ros.actions import Node
import xacro


def launch_setup(context, *args, **kwargs):
rae_description_path = os.path.join(get_package_share_directory(
'rae_description'), 'urdf', 'rae.urdf.xacro')
return [
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(get_package_share_directory('rae_description'), 'launch', 'rsp.launch.py')),
launch_arguments={'sim': 'false',
'namespace': LaunchConfiguration('namespace'),
}.items()
),
Node(
package='rae_hw',
executable='mock_wheels.py',
name='mock_wheels',
namespace=LaunchConfiguration('namespace')
),
Node(
package='rae_hw',
executable='mock_leds.py',
name='mock_leds',
namespace=LaunchConfiguration('namespace')
),
Node(
package='rae_hw',
executable='mock_battery.py',
name='mock_battery',
namespace=LaunchConfiguration('namespace')
),
Node(
package='rae_hw',
executable='mock_lcd.py',
name='mock_lcd',
namespace=LaunchConfiguration('namespace')
),
Node(
package='rae_hw',
executable='mock_speakers.py',
name='mock_speakers',
namespace=LaunchConfiguration('namespace')
),
Node(
package='rae_hw',
executable='mock_mic.py',
name='mock_mic',
namespace=LaunchConfiguration('namespace')
)
]


def generate_launch_description():
declared_arguments = [
DeclareLaunchArgument('name', default_value='rae'),
DeclareLaunchArgument('namespace', default_value=''),
DeclareLaunchArgument('run_container', default_value='true'),
DeclareLaunchArgument('enable_battery_status', default_value='true'),
DeclareLaunchArgument('enable_localization', default_value='true'),
DeclareLaunchArgument('controller_params_file', default_value=os.path.join(get_package_share_directory(
'rae_hw'), 'config', 'controller.yaml')),
]

return LaunchDescription(declared_arguments + [OpaqueFunction(function=launch_setup)])
12 changes: 9 additions & 3 deletions rae_hw/launch/peripherals.launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def launch_setup(context, *args, **kwargs):
ComposableNodeContainer(
condition=IfCondition(run_container),
name=name+'_container',
namespace='',
namespace=LaunchConfiguration('namespace'),
package='rclcpp_components',
executable='component_container',
composable_node_descriptions=[],
Expand All @@ -25,11 +25,13 @@ def launch_setup(context, *args, **kwargs):
composable_node_descriptions=[
ComposableNode(
name='battery_node',
namespace=LaunchConfiguration('namespace'),
package='rae_hw',
plugin='rae_hw::BatteryNode',
),
ComposableNode(
name='lcd_node',
namespace=LaunchConfiguration('namespace'),
package='rae_hw',
plugin='rae_hw::LCDNode',
parameters=[{
Expand All @@ -38,24 +40,28 @@ def launch_setup(context, *args, **kwargs):
),
ComposableNode(
name='led_node',
namespace=LaunchConfiguration('namespace'),
package='rae_hw',
plugin='rae_hw::LEDNode',
)
]),
Node(
package='rae_hw',
executable='mic_node'
executable='mic_node',
namespace=LaunchConfiguration('namespace')
),
Node(
package='rae_hw',
executable='speakers_node'
executable='speakers_node',
namespace=LaunchConfiguration('namespace')
),
]


def generate_launch_description():
declared_arguments = [
DeclareLaunchArgument('name', default_value='rae'),
DeclareLaunchArgument('namespace', default_value=''),
DeclareLaunchArgument('run_container', default_value='true'),
DeclareLaunchArgument('default_logo_path', default_value='/usr/share/rae-logo-white.jpg'),
]
Expand Down
Empty file added rae_hw/rae_hw/__init__.py
Empty file.
22 changes: 22 additions & 0 deletions rae_hw/scripts/mock_battery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node

from sensor_msgs.msg import BatteryState

class MockBattery(Node):
def __init__(self):
super().__init__('mock_battery')
self._battery_pub = self.create_publisher(BatteryState, 'battery', 10)
self.timer = self.create_timer(1, self.timer_callback)

def timer_callback(self):
msg = BatteryState()
self._battery_pub.publish(msg)

if __name__ == '__main__':
rclpy.init()
mock_battery = MockBattery()
rclpy.spin(mock_battery)
mock_battery.destroy_node()
rclpy.shutdown()
19 changes: 19 additions & 0 deletions rae_hw/scripts/mock_lcd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node

from sensor_msgs.msg import Image

class MockLCD(Node):
def __init__(self):
super().__init__('mock_display')
self._image_sub = self.create_subscription(Image, 'lcd', self.image_callback, 10)
def image_callback(self, msg: Image):
self.get_logger().info(f'I heard: {msg.width}, {msg.height}')

if __name__ == '__main__':
rclpy.init()
mock_lcd = MockLCD()
rclpy.spin(mock_lcd)
mock_lcd.destroy_node()
rclpy.shutdown()
19 changes: 19 additions & 0 deletions rae_hw/scripts/mock_leds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node

from rae_msgs.msg import LEDControl

class MockLeds(Node):
def __init__(self):
super().__init__('mock_leds')
self._led_sub = self.create_subscription(LEDControl, 'leds', self.led_callback, 10)
def led_callback(self, msg: LEDControl):
self.get_logger().info('I heard: "%s"' % msg.data)

if __name__ == '__main__':
rclpy.init()
mock_leds = MockLeds()
rclpy.spin(mock_leds)
mock_leds.destroy_node()
rclpy.shutdown()
22 changes: 22 additions & 0 deletions rae_hw/scripts/mock_mic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from audio_msgs.msg import Audio


class MockMic(Node):
def __init__(self):
super().__init__('mock_mic')
self._audio_pub = self.create_publisher(Audio, 'audio_in', 10)
self.timer = self.create_timer(1, self.timer_callback)

def timer_callback(self):
msg = Audio()
self._audio_pub.publish(msg)

if __name__ == '__main__':
rclpy.init()
mock_mic = MockMic()
rclpy.spin(mock_mic)
mock_mic.destroy_node()
rclpy.shutdown()
30 changes: 30 additions & 0 deletions rae_hw/scripts/mock_speakers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node

from audio_msgs.msg import Audio
from rae_msgs.srv import PlayAudio


class MockSpeakers(Node):
def __init__(self):
super().__init__('mock_speakers')
self._audio_sub = self.create_subscription(
Audio, 'audio_out', self.audio_callback, 10)
self._play_service = self.create_service(
PlayAudio, 'play_audio', self.play_callback)

def audio_callback(self, msg: Audio):
self.get_logger().info('I heard: "%s"' % msg.data)

def play_callback(self, request: PlayAudio.Request, response):
self.get_logger().info('I heard: "%s"' % request.mp3_file)
return response


if __name__ == '__main__':
rclpy.init()
mock_speakers = MockSpeakers()
rclpy.spin(mock_speakers)
mock_speakers.destroy_node()
rclpy.shutdown()
Loading

0 comments on commit ddfa241

Please sign in to comment.