Skip to content

Commit 222c1f2

Browse files
committed
ros2 hardware
1 parent 3451af8 commit 222c1f2

11 files changed

Lines changed: 398 additions & 168 deletions

CMakeLists.txt

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ find_package(tf2_ros REQUIRED)
5454
find_package(amrl_msgs REQUIRED)
5555
find_package(amrl_maps REQUIRED)
5656
find_package(rosidl_default_generators REQUIRED)
57+
find_package(rosidl_default_runtime REQUIRED)
5758

5859
FIND_PACKAGE(Qt5 COMPONENTS Core Widgets Gui WebSockets OpenGL REQUIRED)
5960
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
@@ -80,6 +81,24 @@ rosidl_generate_interfaces(${PROJECT_NAME}
8081
DEPENDENCIES geometry_msgs std_msgs sensor_msgs visualization_msgs nav_msgs
8182
)
8283

84+
# Ensure generated message headers are visible to targets in this package
85+
include_directories(${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_cpp)
86+
87+
# Provide the rosidl fastrtps C++ typesupport target for linking against the
88+
# generated type support library for this package's messages.
89+
## Link helper that prefers the generated FastRTPS C++ typesupport target for
90+
## this package, but falls back to the introspection C++ typesupport if the
91+
## fastrtps target isn't available. The generated target names use the
92+
## convention: <pkg>__rosidl_typesupport_fastrtps_cpp.
93+
## Candidate package-specific rosidl typesupport targets. Use generator
94+
## expressions so CMake will link whichever one was generated for this
95+
## package (fastrtps, introspection, or the generic cpp typesupport).
96+
set(UT_AUTOMATA_TYPESUPPORT_LINK
97+
$<TARGET_NAME_IF_EXISTS:${PROJECT_NAME}__rosidl_typesupport_fastrtps_cpp>
98+
$<TARGET_NAME_IF_EXISTS:${PROJECT_NAME}__rosidl_typesupport_introspection_cpp>
99+
$<TARGET_NAME_IF_EXISTS:${PROJECT_NAME}__rosidl_typesupport_cpp>
100+
)
101+
83102
ADD_SUBDIRECTORY(src/shared)
84103
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/shared)
85104

@@ -96,27 +115,33 @@ IF(${CMAKE_BUILD_MODE} MATCHES "Hardware")
96115
src/vesc_driver/vesc_interface.cpp
97116
src/vesc_driver/vesc_packet.cpp
98117
src/vesc_driver/vesc_packet_factory.cpp)
99-
ament_target_dependencies(vesc_driver rclcpp std_msgs geometry_msgs nav_msgs sensor_msgs amrl_msgs)
100-
target_link_libraries(vesc_driver ${libs})
118+
ament_target_dependencies(vesc_driver rclcpp std_msgs geometry_msgs nav_msgs sensor_msgs amrl_msgs rosidl_default_runtime)
119+
target_include_directories(vesc_driver PRIVATE
120+
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_cpp>)
121+
target_link_libraries(vesc_driver ${libs} ${UT_AUTOMATA_TYPESUPPORT_LINK})
101122

102123
add_executable(gui
103124
src/gui/gui_main.cc
104125
src/gui/gui_mainwindow.cc
105126
src/gui/vector_display.cc
106127
${GUI_MOC_SRCS})
107-
ament_target_dependencies(gui rclcpp std_msgs geometry_msgs nav_msgs sensor_msgs amrl_msgs)
128+
ament_target_dependencies(gui rclcpp std_msgs geometry_msgs nav_msgs sensor_msgs amrl_msgs rosidl_default_runtime)
129+
target_include_directories(gui PRIVATE
130+
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_cpp>)
108131
TARGET_LINK_LIBRARIES(gui
109132
Qt5::Core
110133
Qt5::Gui
111134
Qt5::Widgets
112135
Qt5::OpenGL
113-
${libs} ${OPENGL_LIBRARY} GL)
136+
${libs} ${OPENGL_LIBRARY} GL ${UT_AUTOMATA_TYPESUPPORT_LINK})
114137

115138
add_executable(joystick
116139
src/joystick/joystick.cc
117140
src/joystick/joystick_driver.cc)
118-
ament_target_dependencies(joystick rclcpp std_msgs geometry_msgs nav_msgs sensor_msgs amrl_msgs)
119-
target_link_libraries(joystick ${libs})
141+
ament_target_dependencies(joystick rclcpp std_msgs geometry_msgs nav_msgs sensor_msgs amrl_msgs rosidl_default_runtime)
142+
target_include_directories(joystick PRIVATE
143+
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_cpp>)
144+
target_link_libraries(joystick ${libs} ${UT_AUTOMATA_TYPESUPPORT_LINK})
120145

121146
# Install hardware executables for ROS 2
122147
install(TARGETS
@@ -132,27 +157,33 @@ add_executable(simulator
132157
src/simulator/simulator.cc
133158
src/simulator/vector_map.cc
134159
src/simulator/simulator_main.cc)
135-
ament_target_dependencies(simulator rclcpp ament_index_cpp std_msgs geometry_msgs nav_msgs sensor_msgs visualization_msgs amrl_msgs tf2 tf2_geometry_msgs tf2_ros)
136-
target_link_libraries(simulator ${libs})
160+
ament_target_dependencies(simulator rclcpp ament_index_cpp std_msgs geometry_msgs nav_msgs sensor_msgs visualization_msgs amrl_msgs tf2 tf2_geometry_msgs tf2_ros rosidl_default_runtime)
161+
target_include_directories(simulator PRIVATE
162+
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_cpp>)
163+
target_link_libraries(simulator ${libs} ${UT_AUTOMATA_TYPESUPPORT_LINK})
137164

138165
add_executable(step_simulator
139166
src/simulator/simulator.cc
140167
src/simulator/vector_map.cc
141168
src/simulator/step_simulator_main.cc)
142-
ament_target_dependencies(step_simulator rclcpp ament_index_cpp std_msgs geometry_msgs nav_msgs sensor_msgs visualization_msgs amrl_msgs tf2 tf2_geometry_msgs tf2_ros)
143-
target_link_libraries(step_simulator ${libs})
169+
ament_target_dependencies(step_simulator rclcpp ament_index_cpp std_msgs geometry_msgs nav_msgs sensor_msgs visualization_msgs amrl_msgs tf2 tf2_geometry_msgs tf2_ros rosidl_default_runtime)
170+
target_include_directories(step_simulator PRIVATE
171+
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_cpp>)
172+
target_link_libraries(step_simulator ${libs} ${UT_AUTOMATA_TYPESUPPORT_LINK})
144173

145174
add_executable(websocket
146175
src/websocket/websocket_main.cc
147176
src/websocket/websocket.cc
148177
)
149-
ament_target_dependencies(websocket rclcpp ament_index_cpp std_msgs geometry_msgs nav_msgs sensor_msgs amrl_msgs)
178+
ament_target_dependencies(websocket rclcpp ament_index_cpp std_msgs geometry_msgs nav_msgs sensor_msgs amrl_msgs rosidl_default_runtime)
179+
target_include_directories(websocket PRIVATE
180+
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_cpp>)
150181
target_link_libraries(websocket
151182
Qt5::Core
152183
Qt5::Gui
153184
Qt5::Widgets
154185
Qt5::WebSockets
155-
${libs})
186+
${libs} ${UT_AUTOMATA_TYPESUPPORT_LINK})
156187

157188
# Install executables for ROS 2
158189
install(TARGETS

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
build_type=Release
55
# build_type=Debug
66
#acceptable build_mode: Simulation/Hardware
7-
build_mode=Simulation
7+
build_mode=Hardware
88

99
.SILENT:
1010

launch/hokuyo_10lx.launch.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env python3
2+
"""ROS2 launch file port of the ROS1 `hokuyo_10lx.launch`.
3+
4+
This starts the `urg_node` from the `urg_node` package with parameters matching
5+
the original ROS1 launch.
6+
"""
7+
8+
from launch import LaunchDescription
9+
from launch_ros.actions import Node
10+
11+
12+
def generate_launch_description():
13+
ld = LaunchDescription()
14+
15+
ld.add_action(Node(
16+
package='urg_node',
17+
executable='urg_node',
18+
name='urg_node',
19+
output='screen',
20+
parameters=[{
21+
'ip_address': '192.168.0.10',
22+
'serial_port': '',
23+
'serial_baud': 115200,
24+
'frame_id': 'laser',
25+
'calibrate_time': True,
26+
'publish_intensity': False,
27+
'publish_multiecho': False,
28+
'angle_min': -2.25,
29+
'angle_max': 2.25,
30+
}],
31+
))
32+
33+
return ld

launch/logging.launch.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env python3
2+
"""ROS2 launch file port of the ROS1 `logging.launch`.
3+
4+
Starts the `logger` node from `ut_automata` with an `--out_dir` argument.
5+
"""
6+
7+
from launch import LaunchDescription
8+
from launch.actions import DeclareLaunchArgument
9+
from launch.substitutions import LaunchConfiguration
10+
from launch_ros.actions import Node
11+
12+
13+
def generate_launch_description():
14+
out_dir = LaunchConfiguration('out_dir')
15+
16+
ld = LaunchDescription()
17+
18+
ld.add_action(DeclareLaunchArgument(
19+
'out_dir', default_value='/home/amrl_user/bagfiles/',
20+
description='Directory where logger will write bagfiles'))
21+
22+
ld.add_action(Node(
23+
package='ut_automata',
24+
executable='logger',
25+
name='logger',
26+
output='screen',
27+
arguments=['--out_dir', out_dir],
28+
respawn=False,
29+
))
30+
31+
return ld

launch/start_car.launch.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#!/usr/bin/env python3
2+
"""ROS2 launch file port of the ROS1 `start_car.launch`.
3+
4+
This starts the hokuyo include (assumed converted to a ROS2 python launch),
5+
and launches the vesc_driver, websocket, joystick and gui nodes. The gui
6+
node is controlled by the `start_gui` launch argument.
7+
8+
Assumptions:
9+
- A ROS2-compatible `hokuyo_10lx` launch exists at
10+
`launch/hokuyo_10lx.launch.py` inside the `ut_automata` package.
11+
- The package `ut_automata` exposes executables named
12+
`vesc_driver`, `websocket`, `joystick`, and `gui`.
13+
"""
14+
15+
import os
16+
17+
from launch import LaunchDescription
18+
from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription
19+
from launch.conditions import IfCondition
20+
from launch.substitutions import LaunchConfiguration
21+
from launch.launch_description_sources import PythonLaunchDescriptionSource
22+
from launch_ros.actions import Node
23+
24+
from ament_index_python.packages import get_package_share_directory
25+
26+
27+
def generate_launch_description():
28+
start_gui = LaunchConfiguration('start_gui')
29+
30+
# package share and paths
31+
pkg_share = get_package_share_directory('ut_automata')
32+
config_dir = os.path.join(pkg_share, 'config')
33+
hokuyo_launch = os.path.join(pkg_share, 'launch', 'hokuyo_10lx.launch.py')
34+
35+
ld = LaunchDescription()
36+
37+
ld.add_action(DeclareLaunchArgument(
38+
'start_gui', default_value='true', description='Enable to start up the gui'))
39+
40+
# Include hokuyo launch (assumes a ROS2 python launch exists at the path above)
41+
if os.path.exists(hokuyo_launch):
42+
ld.add_action(IncludeLaunchDescription(
43+
PythonLaunchDescriptionSource(hokuyo_launch)
44+
))
45+
else:
46+
# If the hokuyo launch isn't present, we still continue but users should
47+
# convert or add the hokuyo launch file at the expected location.
48+
pass
49+
50+
# vesc_driver node
51+
ld.add_action(Node(
52+
package='ut_automata',
53+
executable='vesc_driver',
54+
name='vesc_driver',
55+
output='screen',
56+
arguments=['--config_dir', config_dir],
57+
respawn=True,
58+
respawn_delay=5.0,
59+
))
60+
61+
# websocket node
62+
ld.add_action(Node(
63+
package='ut_automata',
64+
executable='websocket',
65+
name='websocket',
66+
output='screen',
67+
respawn=True,
68+
respawn_delay=2.0,
69+
))
70+
71+
# joystick node
72+
ld.add_action(Node(
73+
package='ut_automata',
74+
executable='joystick',
75+
name='joystick',
76+
output='screen',
77+
arguments=['--config_dir', config_dir],
78+
respawn=True,
79+
respawn_delay=2.0,
80+
))
81+
82+
# gui node, only if start_gui is true
83+
ld.add_action(Node(
84+
package='ut_automata',
85+
executable='gui',
86+
name='gui',
87+
output='screen',
88+
respawn=False,
89+
condition=IfCondition(start_gui),
90+
))
91+
92+
return ld

0 commit comments

Comments
 (0)