Skip to content

Commit b64969b

Browse files
authored
Merge pull request #119 from azazdeaz/humble
Add tricycle example to the `humble` branch
2 parents 5b87cf3 + 88b8f13 commit b64969b

File tree

7 files changed

+397
-0
lines changed

7 files changed

+397
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ ros2 launch ign_ros2_control_demos cart_example_position.launch.py
219219
ros2 launch ign_ros2_control_demos cart_example_velocity.launch.py
220220
ros2 launch ign_ros2_control_demos cart_example_effort.launch.py
221221
ros2 launch ign_ros2_control_demos diff_drive_example.launch.py
222+
ros2 launch ign_ros2_control_demos tricycle_drive_example.launch.py
222223
```
223224

224225
Send example commands:
@@ -230,4 +231,5 @@ ros2 run ign_ros2_control_demos example_position
230231
ros2 run ign_ros2_control_demos example_velocity
231232
ros2 run ign_ros2_control_demos example_effort
232233
ros2 run ign_ros2_control_demos example_diff_drive
234+
ros2 run ign_ros2_control_demos example_tricycle_drive
233235
```

ign_ros2_control_demos/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ ament_target_dependencies(example_diff_drive
5353
geometry_msgs
5454
)
5555

56+
add_executable(example_tricycle_drive examples/example_tricycle_drive.cpp)
57+
ament_target_dependencies(example_tricycle_drive
58+
rclcpp
59+
geometry_msgs
60+
)
61+
5662
if(BUILD_TESTING)
5763
find_package(ament_cmake_gtest REQUIRED)
5864
find_package(ament_lint_auto REQUIRED)
@@ -67,6 +73,7 @@ install(
6773
example_velocity
6874
example_effort
6975
example_diff_drive
76+
example_tricycle_drive
7077
DESTINATION
7178
lib/${PROJECT_NAME}
7279
)
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
controller_manager:
2+
ros__parameters:
3+
update_rate: 50 # Hz
4+
5+
tricycle_controller:
6+
type: tricycle_controller/TricycleController
7+
8+
joint_state_broadcaster:
9+
type: joint_state_broadcaster/JointStateBroadcaster
10+
11+
joint_state_broadcaster:
12+
ros__parameters:
13+
extra_joints: ["right_wheel_joint", "left_wheel_joint"]
14+
15+
tricycle_controller:
16+
ros__parameters:
17+
# Model
18+
traction_joint_name: traction_joint # Name of traction joint in URDF
19+
steering_joint_name: steering_joint # Name of steering joint in URDF
20+
wheel_radius: 0.3 # Radius of front wheel
21+
wheelbase: 1.7 # Distance between center of back wheels and front wheel
22+
23+
# Odometry
24+
odom_frame_id: odom
25+
base_frame_id: base_link
26+
publish_rate: 50.0 # publish rate of odom and tf
27+
open_loop: false # if True, uses cmd_vel instead of hardware interface feedback to compute odometry
28+
enable_odom_tf: true # If True, publishes odom<-base_link TF
29+
odom_only_twist: false # If True, publishes on /odom only linear.x and angular.z; Useful for computing odometry in another node, e.g robot_localization's ekf
30+
pose_covariance_diagonal: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] # Need to be set if fusing odom with other localization source
31+
twist_covariance_diagonal: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] # Need to be set if fusing odom with other localization source
32+
velocity_rolling_window_size: 10 # Rolling window size of rcppmath::RollingMeanAccumulator applied on linear and angular speeds published on odom
33+
34+
# Rate Limiting
35+
traction: # All values should be positive
36+
# min_velocity: 0.0
37+
# max_velocity: 1000.0
38+
# min_acceleration: 0.0
39+
max_acceleration: 5.0
40+
# min_deceleration: 0.0
41+
max_deceleration: 8.0
42+
# min_jerk: 0.0
43+
# max_jerk: 1000.0
44+
steering:
45+
min_position: -1.57
46+
max_position: 1.57
47+
# min_velocity: 0.0
48+
max_velocity: 1.0
49+
# min_acceleration: 0.0
50+
# max_acceleration: 1000.0
51+
52+
# cmd_vel input
53+
cmd_vel_timeout: 500 # In milliseconds. Timeout to stop if no cmd_vel is received
54+
use_stamped_vel: false # Set to True if using TwistStamped.
55+
56+
# Debug
57+
publish_ackermann_command: true # Publishes AckermannDrive. The speed does not comply to the msg definition, it the wheel angular speed in rad/s.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2022 Open Source Robotics Foundation, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <memory>
16+
17+
#include <rclcpp/rclcpp.hpp>
18+
19+
#include <geometry_msgs/msg/twist.hpp>
20+
21+
using namespace std::chrono_literals;
22+
23+
int main(int argc, char * argv[])
24+
{
25+
rclcpp::init(argc, argv);
26+
27+
std::shared_ptr<rclcpp::Node> node =
28+
std::make_shared<rclcpp::Node>("tricycle_drive_test_node");
29+
30+
auto publisher = node->create_publisher<geometry_msgs::msg::Twist>(
31+
"/tricycle_controller/cmd_vel", 10);
32+
33+
RCLCPP_INFO(node->get_logger(), "node created");
34+
35+
geometry_msgs::msg::Twist command;
36+
37+
command.linear.x = 0.2;
38+
command.linear.y = 0.0;
39+
command.linear.z = 0.0;
40+
41+
command.angular.x = 0.0;
42+
command.angular.y = 0.0;
43+
command.angular.z = 0.1;
44+
45+
while (1) {
46+
publisher->publish(command);
47+
std::this_thread::sleep_for(50ms);
48+
rclcpp::spin_some(node);
49+
}
50+
rclcpp::shutdown();
51+
52+
return 0;
53+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Copyright 2022 Open Source Robotics Foundation, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
17+
from ament_index_python.packages import get_package_share_directory
18+
19+
from launch import LaunchDescription
20+
from launch.actions import DeclareLaunchArgument, ExecuteProcess, IncludeLaunchDescription
21+
from launch.actions import RegisterEventHandler
22+
from launch.event_handlers import OnProcessExit
23+
from launch.launch_description_sources import PythonLaunchDescriptionSource
24+
from launch.substitutions import LaunchConfiguration
25+
26+
from launch_ros.actions import Node
27+
28+
import xacro
29+
30+
31+
def generate_launch_description():
32+
# Launch Arguments
33+
use_sim_time = LaunchConfiguration('use_sim_time', default=True)
34+
35+
ignition_ros2_control_demos_path = os.path.join(
36+
get_package_share_directory('ign_ros2_control_demos'))
37+
38+
xacro_file = os.path.join(ignition_ros2_control_demos_path,
39+
'urdf',
40+
'test_tricycle_drive.xacro.urdf')
41+
42+
doc = xacro.parse(open(xacro_file))
43+
xacro.process_doc(doc)
44+
params = {'robot_description': doc.toxml()}
45+
46+
print(params)
47+
48+
node_robot_state_publisher = Node(
49+
package='robot_state_publisher',
50+
executable='robot_state_publisher',
51+
output='screen',
52+
parameters=[params],
53+
)
54+
55+
ignition_spawn_entity = Node(
56+
package='ros_gz_sim',
57+
executable='create',
58+
output='screen',
59+
arguments=['-string', doc.toxml(),
60+
'-name', 'cartpole',
61+
'-allow_renaming', 'true'],
62+
)
63+
64+
load_joint_state_controller = ExecuteProcess(
65+
cmd=['ros2', 'control', 'load_controller', '--set-state', 'active',
66+
'joint_state_broadcaster'],
67+
output='screen'
68+
)
69+
70+
load_joint_trajectory_controller = ExecuteProcess(
71+
cmd=['ros2', 'control', 'load_controller', '--set-state', 'active',
72+
'tricycle_controller'],
73+
output='screen'
74+
)
75+
76+
return LaunchDescription([
77+
# Launch gazebo environment
78+
IncludeLaunchDescription(
79+
PythonLaunchDescriptionSource(
80+
[os.path.join(get_package_share_directory('ros_gz_sim'),
81+
'launch', 'gz_sim.launch.py')]),
82+
launch_arguments=[('ign_args', [' -r -v 4 empty.sdf'])]),
83+
RegisterEventHandler(
84+
event_handler=OnProcessExit(
85+
target_action=ignition_spawn_entity,
86+
on_exit=[load_joint_state_controller],
87+
)
88+
),
89+
RegisterEventHandler(
90+
event_handler=OnProcessExit(
91+
target_action=load_joint_state_controller,
92+
on_exit=[load_joint_trajectory_controller],
93+
)
94+
),
95+
node_robot_state_publisher,
96+
ignition_spawn_entity,
97+
# Launch Arguments
98+
DeclareLaunchArgument(
99+
'use_sim_time',
100+
default_value=use_sim_time,
101+
description='If true, use simulated clock'),
102+
])

ign_ros2_control_demos/package.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
<exec_depend>std_msgs</exec_depend>
4141
<exec_depend>velocity_controllers</exec_depend>
4242
<exec_depend>diff_drive_controller</exec_depend>
43+
<exec_depend>tricycle_controller</exec_depend>
4344
<exec_depend>xacro</exec_depend>
4445

4546
<test_depend>ament_cmake_gtest</test_depend>

0 commit comments

Comments
 (0)