├── .gitignore ├── LICENSE ├── README.md ├── Section10_Probability_for_Robotics └── bumperbot_ws │ └── src │ ├── bumperbot_controller │ ├── CMakeLists.txt │ ├── bumperbot_controller │ │ ├── __init__.py │ │ ├── noisy_controller.py │ │ └── simple_controller.py │ ├── config │ │ ├── bumperbot_controllers.yaml │ │ ├── joy_config.yaml │ │ └── joy_teleop.yaml │ ├── include │ │ └── bumperbot_controller │ │ │ ├── noisy_controller.hpp │ │ │ └── simple_controller.hpp │ ├── launch │ │ ├── controller.launch.py │ │ └── joystick_teleop.launch.py │ ├── package.xml │ └── src │ │ ├── noisy_controller.cpp │ │ └── simple_controller.cpp │ ├── bumperbot_cpp_examples │ ├── CMakeLists.txt │ ├── include │ │ └── bumperbot_cpp_examples │ │ │ ├── simple_tf_kinematics.hpp │ │ │ └── simple_turtlesim_kinematics.hpp │ ├── package.xml │ └── src │ │ ├── simple_parameter.cpp │ │ ├── simple_publisher.cpp │ │ ├── simple_service_client.cpp │ │ ├── simple_service_server.cpp │ │ ├── simple_subscriber.cpp │ │ ├── simple_tf_kinematics.cpp │ │ └── simple_turtlesim_kinematics.cpp │ ├── bumperbot_description │ ├── CMakeLists.txt │ ├── launch │ │ ├── display.launch.py │ │ └── gazebo.launch.py │ ├── meshes │ │ ├── base_link.STL │ │ ├── caster_front_link.STL │ │ ├── caster_rear_link.STL │ │ ├── imu_link.STL │ │ ├── wheel_left_link.STL │ │ └── wheel_right_link.STL │ ├── package.xml │ ├── rviz │ │ └── display.rviz │ └── urdf │ │ ├── bumperbot.urdf.xacro │ │ ├── bumperbot_gazebo.xacro │ │ └── bumperbot_ros2_control.xacro │ ├── bumperbot_msgs │ ├── CMakeLists.txt │ ├── package.xml │ └── srv │ │ ├── AddTwoInts.srv │ │ └── GetTransform.srv │ └── bumperbot_py_examples │ ├── bumperbot_py_examples │ ├── __init__.py │ ├── simple_parameter.py │ ├── simple_publisher.py │ ├── simple_service_client.py │ ├── simple_service_server.py │ ├── simple_subscriber.py │ ├── simple_tf_kinematics.py │ └── simple_turtlesim_kinematics.py │ ├── package.xml │ ├── resource │ └── bumperbot_py_examples │ ├── setup.cfg │ ├── setup.py │ └── test │ ├── test_copyright.py │ ├── test_flake8.py │ └── test_pep257.py ├── Section11_Sensor_Fusion └── bumperbot_ws │ └── src │ ├── bumperbot_controller │ ├── CMakeLists.txt │ ├── bumperbot_controller │ │ ├── __init__.py │ │ ├── noisy_controller.py │ │ └── simple_controller.py │ ├── config │ │ ├── bumperbot_controllers.yaml │ │ ├── joy_config.yaml │ │ └── joy_teleop.yaml │ ├── include │ │ └── bumperbot_controller │ │ │ ├── noisy_controller.hpp │ │ │ └── simple_controller.hpp │ ├── launch │ │ ├── controller.launch.py │ │ └── joystick_teleop.launch.py │ ├── package.xml │ └── src │ │ ├── noisy_controller.cpp │ │ └── simple_controller.cpp │ ├── bumperbot_cpp_examples │ ├── CMakeLists.txt │ ├── include │ │ └── bumperbot_cpp_examples │ │ │ ├── simple_tf_kinematics.hpp │ │ │ └── simple_turtlesim_kinematics.hpp │ ├── package.xml │ └── src │ │ ├── simple_parameter.cpp │ │ ├── simple_publisher.cpp │ │ ├── simple_service_client.cpp │ │ ├── simple_service_server.cpp │ │ ├── simple_subscriber.cpp │ │ ├── simple_tf_kinematics.cpp │ │ └── simple_turtlesim_kinematics.cpp │ ├── bumperbot_description │ ├── CMakeLists.txt │ ├── launch │ │ ├── display.launch.py │ │ └── gazebo.launch.py │ ├── meshes │ │ ├── base_link.STL │ │ ├── caster_front_link.STL │ │ ├── caster_rear_link.STL │ │ ├── imu_link.STL │ │ ├── wheel_left_link.STL │ │ └── wheel_right_link.STL │ ├── package.xml │ ├── rviz │ │ └── display.rviz │ └── urdf │ │ ├── bumperbot.urdf.xacro │ │ ├── bumperbot_gazebo.xacro │ │ └── bumperbot_ros2_control.xacro │ ├── bumperbot_localization │ ├── CMakeLists.txt │ ├── bumperbot_localization │ │ ├── __init__.py │ │ ├── imu_republisher.py │ │ └── kalman_filter.py │ ├── config │ │ └── ekf.yaml │ ├── include │ │ └── bumperbot_localization │ │ │ └── kalman_filter.hpp │ ├── launch │ │ └── local_localization.launch.py │ ├── package.xml │ └── src │ │ ├── imu_republisher.cpp │ │ └── kalman_filter.cpp │ ├── bumperbot_msgs │ ├── CMakeLists.txt │ ├── package.xml │ └── srv │ │ ├── AddTwoInts.srv │ │ └── GetTransform.srv │ └── bumperbot_py_examples │ ├── bumperbot_py_examples │ ├── __init__.py │ ├── simple_parameter.py │ ├── simple_publisher.py │ ├── simple_service_client.py │ ├── simple_service_server.py │ ├── simple_subscriber.py │ ├── simple_tf_kinematics.py │ └── simple_turtlesim_kinematics.py │ ├── package.xml │ ├── resource │ └── bumperbot_py_examples │ ├── setup.cfg │ ├── setup.py │ └── test │ ├── test_copyright.py │ ├── test_flake8.py │ └── test_pep257.py ├── Section12_Build_the_Robot └── bumperbot_ws │ └── src │ ├── bumperbot_bringup │ ├── CMakeLists.txt │ ├── launch │ │ ├── real_robot.launch.py │ │ └── simulated_robot.launch.py │ └── package.xml │ ├── bumperbot_controller │ ├── CMakeLists.txt │ ├── bumperbot_controller │ │ ├── __init__.py │ │ ├── noisy_controller.py │ │ └── simple_controller.py │ ├── config │ │ ├── bumperbot_controllers.yaml │ │ ├── joy_config.yaml │ │ └── joy_teleop.yaml │ ├── include │ │ └── bumperbot_controller │ │ │ ├── noisy_controller.hpp │ │ │ └── simple_controller.hpp │ ├── launch │ │ ├── controller.launch.py │ │ └── joystick_teleop.launch.py │ ├── package.xml │ └── src │ │ ├── noisy_controller.cpp │ │ └── simple_controller.cpp │ ├── bumperbot_cpp_examples │ ├── CMakeLists.txt │ ├── include │ │ └── bumperbot_cpp_examples │ │ │ ├── simple_tf_kinematics.hpp │ │ │ └── simple_turtlesim_kinematics.hpp │ ├── package.xml │ └── src │ │ ├── simple_lifecycle_node.cpp │ │ ├── simple_parameter.cpp │ │ ├── simple_publisher.cpp │ │ ├── simple_service_client.cpp │ │ ├── simple_service_server.cpp │ │ ├── simple_subscriber.cpp │ │ ├── simple_tf_kinematics.cpp │ │ └── simple_turtlesim_kinematics.cpp │ ├── bumperbot_description │ ├── CMakeLists.txt │ ├── launch │ │ ├── display.launch.py │ │ └── gazebo.launch.py │ ├── meshes │ │ ├── base_link.STL │ │ ├── caster_front_link.STL │ │ ├── caster_rear_link.STL │ │ ├── imu_link.STL │ │ ├── wheel_left_link.STL │ │ └── wheel_right_link.STL │ ├── package.xml │ ├── rviz │ │ └── display.rviz │ └── urdf │ │ ├── bumperbot.urdf.xacro │ │ ├── bumperbot_gazebo.xacro │ │ └── bumperbot_ros2_control.xacro │ ├── bumperbot_firmware │ ├── CMakeLists.txt │ ├── bumperbot_firmware │ │ ├── __init__.py │ │ ├── mpu6050_driver.py │ │ ├── simple_serial_receiver.py │ │ └── simple_serial_transmitter.py │ ├── bumperbot_interface.xml │ ├── firmware │ │ ├── robot_control │ │ │ └── robot_control.ino │ │ ├── robot_control_inverted │ │ │ └── robot_control_inverted.ino │ │ ├── simple_encoder_reader │ │ │ └── simple_encoder_reader.ino │ │ ├── simple_motor_control │ │ │ └── simple_motor_control.ino │ │ ├── simple_serial_receiver │ │ │ └── simple_serial_receiver.ino │ │ └── simple_serial_transmitter │ │ │ └── simple_serial_transmitter.ino │ ├── include │ │ └── bumperbot_firmware │ │ │ └── bumperbot_interface.hpp │ ├── launch │ │ └── hardware_interface.launch.py │ ├── package.xml │ └── src │ │ ├── bumperbot_interface.cpp │ │ ├── simple_serial_receiver.cpp │ │ └── simple_serial_transmitter.cpp │ ├── bumperbot_localization │ ├── CMakeLists.txt │ ├── bumperbot_localization │ │ ├── __init__.py │ │ ├── imu_republisher.py │ │ └── kalman_filter.py │ ├── config │ │ └── ekf.yaml │ ├── include │ │ └── bumperbot_localization │ │ │ └── kalman_filter.hpp │ ├── launch │ │ └── local_localization.launch.py │ ├── package.xml │ └── src │ │ ├── imu_republisher.cpp │ │ └── kalman_filter.cpp │ ├── bumperbot_msgs │ ├── CMakeLists.txt │ ├── package.xml │ └── srv │ │ ├── AddTwoInts.srv │ │ └── GetTransform.srv │ └── bumperbot_py_examples │ ├── bumperbot_py_examples │ ├── __init__.py │ ├── simple_lifecycle_node.py │ ├── simple_parameter.py │ ├── simple_publisher.py │ ├── simple_service_client.py │ ├── simple_service_server.py │ ├── simple_subscriber.py │ ├── simple_tf_kinematics.py │ └── simple_turtlesim_kinematics.py │ ├── package.xml │ ├── resource │ └── bumperbot_py_examples │ ├── setup.cfg │ ├── setup.py │ └── test │ ├── test_copyright.py │ ├── test_flake8.py │ └── test_pep257.py ├── Section3_Introduction_to_ROS_2 └── bumperbot_ws │ └── src │ ├── bumperbot_cpp_examples │ ├── CMakeLists.txt │ ├── package.xml │ └── src │ │ ├── simple_publisher.cpp │ │ └── simple_subscriber.cpp │ └── bumperbot_py_examples │ ├── bumperbot_py_examples │ ├── __init__.py │ ├── simple_publisher.py │ └── simple_subscriber.py │ ├── package.xml │ ├── resource │ └── bumperbot_py_examples │ ├── setup.cfg │ ├── setup.py │ └── test │ ├── test_copyright.py │ ├── test_flake8.py │ └── test_pep257.py ├── Section4_Locomotion └── bumperbot_ws │ └── src │ ├── bumperbot_cpp_examples │ ├── CMakeLists.txt │ ├── package.xml │ └── src │ │ ├── simple_parameter.cpp │ │ ├── simple_publisher.cpp │ │ └── simple_subscriber.cpp │ ├── bumperbot_description │ ├── CMakeLists.txt │ ├── launch │ │ ├── display.launch.py │ │ └── gazebo.launch.py │ ├── meshes │ │ ├── base_link.STL │ │ ├── caster_front_link.STL │ │ ├── caster_rear_link.STL │ │ ├── imu_link.STL │ │ ├── wheel_left_link.STL │ │ └── wheel_right_link.STL │ ├── package.xml │ ├── rviz │ │ └── display.rviz │ └── urdf │ │ ├── bumperbot.urdf.xacro │ │ └── bumperbot_gazebo.xacro │ └── bumperbot_py_examples │ ├── bumperbot_py_examples │ ├── __init__.py │ ├── simple_parameter.py │ ├── simple_publisher.py │ └── simple_subscriber.py │ ├── package.xml │ ├── resource │ └── bumperbot_py_examples │ ├── setup.cfg │ ├── setup.py │ └── test │ ├── test_copyright.py │ ├── test_flake8.py │ └── test_pep257.py ├── Section5_Control └── bumperbot_ws │ └── src │ ├── bumperbot_controller │ ├── CMakeLists.txt │ ├── config │ │ └── bumperbot_controllers.yaml │ ├── launch │ │ └── controller.launch.py │ └── package.xml │ ├── bumperbot_cpp_examples │ ├── CMakeLists.txt │ ├── package.xml │ └── src │ │ ├── simple_parameter.cpp │ │ ├── simple_publisher.cpp │ │ └── simple_subscriber.cpp │ ├── bumperbot_description │ ├── CMakeLists.txt │ ├── launch │ │ ├── display.launch.py │ │ └── gazebo.launch.py │ ├── meshes │ │ ├── base_link.STL │ │ ├── caster_front_link.STL │ │ ├── caster_rear_link.STL │ │ ├── imu_link.STL │ │ ├── wheel_left_link.STL │ │ └── wheel_right_link.STL │ ├── package.xml │ ├── rviz │ │ └── display.rviz │ └── urdf │ │ ├── bumperbot.urdf.xacro │ │ ├── bumperbot_gazebo.xacro │ │ └── bumperbot_ros2_control.xacro │ └── bumperbot_py_examples │ ├── bumperbot_py_examples │ ├── __init__.py │ ├── simple_parameter.py │ ├── simple_publisher.py │ └── simple_subscriber.py │ ├── package.xml │ ├── resource │ └── bumperbot_py_examples │ ├── setup.cfg │ ├── setup.py │ └── test │ ├── test_copyright.py │ ├── test_flake8.py │ └── test_pep257.py ├── Section6_Kinematics └── bumperbot_ws │ └── src │ ├── bumperbot_controller │ ├── CMakeLists.txt │ ├── config │ │ └── bumperbot_controllers.yaml │ ├── launch │ │ └── controller.launch.py │ └── package.xml │ ├── bumperbot_cpp_examples │ ├── CMakeLists.txt │ ├── include │ │ └── bumperbot_cpp_examples │ │ │ └── simple_turtlesim_kinematics.hpp │ ├── package.xml │ └── src │ │ ├── simple_parameter.cpp │ │ ├── simple_publisher.cpp │ │ ├── simple_subscriber.cpp │ │ └── simple_turtlesim_kinematics.cpp │ ├── bumperbot_description │ ├── CMakeLists.txt │ ├── launch │ │ ├── display.launch.py │ │ └── gazebo.launch.py │ ├── meshes │ │ ├── base_link.STL │ │ ├── caster_front_link.STL │ │ ├── caster_rear_link.STL │ │ ├── imu_link.STL │ │ ├── wheel_left_link.STL │ │ └── wheel_right_link.STL │ ├── package.xml │ ├── rviz │ │ └── display.rviz │ └── urdf │ │ ├── bumperbot.urdf.xacro │ │ ├── bumperbot_gazebo.xacro │ │ └── bumperbot_ros2_control.xacro │ └── bumperbot_py_examples │ ├── bumperbot_py_examples │ ├── __init__.py │ ├── simple_parameter.py │ ├── simple_publisher.py │ ├── simple_subscriber.py │ └── simple_turtlesim_kinematics.py │ ├── package.xml │ ├── resource │ └── bumperbot_py_examples │ ├── setup.cfg │ ├── setup.py │ └── test │ ├── test_copyright.py │ ├── test_flake8.py │ └── test_pep257.py ├── Section7_Differential_Kinematics └── bumperbot_ws │ └── src │ ├── bumperbot_controller │ ├── CMakeLists.txt │ ├── bumperbot_controller │ │ ├── __init__.py │ │ └── simple_controller.py │ ├── config │ │ ├── bumperbot_controllers.yaml │ │ ├── joy_config.yaml │ │ └── joy_teleop.yaml │ ├── include │ │ └── bumperbot_controller │ │ │ └── simple_controller.hpp │ ├── launch │ │ ├── controller.launch.py │ │ └── joystick_teleop.launch.py │ ├── package.xml │ └── src │ │ └── simple_controller.cpp │ ├── bumperbot_cpp_examples │ ├── CMakeLists.txt │ ├── include │ │ └── bumperbot_cpp_examples │ │ │ └── simple_turtlesim_kinematics.hpp │ ├── package.xml │ └── src │ │ ├── simple_parameter.cpp │ │ ├── simple_publisher.cpp │ │ ├── simple_subscriber.cpp │ │ └── simple_turtlesim_kinematics.cpp │ ├── bumperbot_description │ ├── CMakeLists.txt │ ├── launch │ │ ├── display.launch.py │ │ └── gazebo.launch.py │ ├── meshes │ │ ├── base_link.STL │ │ ├── caster_front_link.STL │ │ ├── caster_rear_link.STL │ │ ├── imu_link.STL │ │ ├── wheel_left_link.STL │ │ └── wheel_right_link.STL │ ├── package.xml │ ├── rviz │ │ └── display.rviz │ └── urdf │ │ ├── bumperbot.urdf.xacro │ │ ├── bumperbot_gazebo.xacro │ │ └── bumperbot_ros2_control.xacro │ └── bumperbot_py_examples │ ├── bumperbot_py_examples │ ├── __init__.py │ ├── simple_parameter.py │ ├── simple_publisher.py │ ├── simple_subscriber.py │ └── simple_turtlesim_kinematics.py │ ├── package.xml │ ├── resource │ └── bumperbot_py_examples │ ├── setup.cfg │ ├── setup.py │ └── test │ ├── test_copyright.py │ ├── test_flake8.py │ └── test_pep257.py ├── Section8_TF2_Library └── bumperbot_ws │ └── src │ ├── bumperbot_controller │ ├── CMakeLists.txt │ ├── bumperbot_controller │ │ ├── __init__.py │ │ └── simple_controller.py │ ├── config │ │ ├── bumperbot_controllers.yaml │ │ ├── joy_config.yaml │ │ └── joy_teleop.yaml │ ├── include │ │ └── bumperbot_controller │ │ │ └── simple_controller.hpp │ ├── launch │ │ ├── controller.launch.py │ │ └── joystick_teleop.launch.py │ ├── package.xml │ └── src │ │ └── simple_controller.cpp │ ├── bumperbot_cpp_examples │ ├── CMakeLists.txt │ ├── include │ │ └── bumperbot_cpp_examples │ │ │ ├── simple_tf_kinematics.hpp │ │ │ └── simple_turtlesim_kinematics.hpp │ ├── package.xml │ └── src │ │ ├── simple_parameter.cpp │ │ ├── simple_publisher.cpp │ │ ├── simple_service_client.cpp │ │ ├── simple_service_server.cpp │ │ ├── simple_subscriber.cpp │ │ ├── simple_tf_kinematics.cpp │ │ └── simple_turtlesim_kinematics.cpp │ ├── bumperbot_description │ ├── CMakeLists.txt │ ├── launch │ │ ├── display.launch.py │ │ └── gazebo.launch.py │ ├── meshes │ │ ├── base_link.STL │ │ ├── caster_front_link.STL │ │ ├── caster_rear_link.STL │ │ ├── imu_link.STL │ │ ├── wheel_left_link.STL │ │ └── wheel_right_link.STL │ ├── package.xml │ ├── rviz │ │ └── display.rviz │ └── urdf │ │ ├── bumperbot.urdf.xacro │ │ ├── bumperbot_gazebo.xacro │ │ └── bumperbot_ros2_control.xacro │ ├── bumperbot_msgs │ ├── CMakeLists.txt │ ├── package.xml │ └── srv │ │ ├── AddTwoInts.srv │ │ └── GetTransform.srv │ └── bumperbot_py_examples │ ├── bumperbot_py_examples │ ├── __init__.py │ ├── simple_parameter.py │ ├── simple_publisher.py │ ├── simple_service_client.py │ ├── simple_service_server.py │ ├── simple_subscriber.py │ ├── simple_tf_kinematics.py │ └── simple_turtlesim_kinematics.py │ ├── package.xml │ ├── resource │ └── bumperbot_py_examples │ ├── setup.cfg │ ├── setup.py │ └── test │ ├── test_copyright.py │ ├── test_flake8.py │ └── test_pep257.py ├── Section9_Odometry └── bumperbot_ws │ └── src │ ├── bumperbot_controller │ ├── CMakeLists.txt │ ├── bumperbot_controller │ │ ├── __init__.py │ │ └── simple_controller.py │ ├── config │ │ ├── bumperbot_controllers.yaml │ │ ├── joy_config.yaml │ │ └── joy_teleop.yaml │ ├── include │ │ └── bumperbot_controller │ │ │ └── simple_controller.hpp │ ├── launch │ │ ├── controller.launch.py │ │ └── joystick_teleop.launch.py │ ├── package.xml │ └── src │ │ └── simple_controller.cpp │ ├── bumperbot_cpp_examples │ ├── CMakeLists.txt │ ├── include │ │ └── bumperbot_cpp_examples │ │ │ ├── simple_tf_kinematics.hpp │ │ │ └── simple_turtlesim_kinematics.hpp │ ├── package.xml │ └── src │ │ ├── simple_parameter.cpp │ │ ├── simple_publisher.cpp │ │ ├── simple_service_client.cpp │ │ ├── simple_service_server.cpp │ │ ├── simple_subscriber.cpp │ │ ├── simple_tf_kinematics.cpp │ │ └── simple_turtlesim_kinematics.cpp │ ├── bumperbot_description │ ├── CMakeLists.txt │ ├── launch │ │ ├── display.launch.py │ │ └── gazebo.launch.py │ ├── meshes │ │ ├── base_link.STL │ │ ├── caster_front_link.STL │ │ ├── caster_rear_link.STL │ │ ├── imu_link.STL │ │ ├── wheel_left_link.STL │ │ └── wheel_right_link.STL │ ├── package.xml │ ├── rviz │ │ └── display.rviz │ └── urdf │ │ ├── bumperbot.urdf.xacro │ │ ├── bumperbot_gazebo.xacro │ │ └── bumperbot_ros2_control.xacro │ ├── bumperbot_msgs │ ├── CMakeLists.txt │ ├── package.xml │ └── srv │ │ ├── AddTwoInts.srv │ │ └── GetTransform.srv │ └── bumperbot_py_examples │ ├── bumperbot_py_examples │ ├── __init__.py │ ├── simple_parameter.py │ ├── simple_publisher.py │ ├── simple_service_client.py │ ├── simple_service_server.py │ ├── simple_subscriber.py │ ├── simple_tf_kinematics.py │ └── simple_turtlesim_kinematics.py │ ├── package.xml │ ├── resource │ └── bumperbot_py_examples │ ├── setup.cfg │ ├── setup.py │ └── test │ ├── test_copyright.py │ ├── test_flake8.py │ └── test_pep257.py └── images ├── cover_manipulators.png ├── cover_map_localization.png ├── cover_odometry_control.png └── cover_plan_navigation.png /.gitignore: -------------------------------------------------------------------------------- 1 | **/install 2 | **/build 3 | **/log* 4 | **/.catkin_workspace 5 | **/.vscode 6 | **.pyc -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_controller/bumperbot_controller/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_controller/bumperbot_controller/__init__.py -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_controller/config/joy_config.yaml: -------------------------------------------------------------------------------- 1 | joystick: 2 | ros__parameters: 3 | device_id: 0 4 | device_name: "" 5 | deadzone: 0.5 6 | autorepeat_rate: 20.0 7 | sticky_buttons: false 8 | coalesce_interval_ms: 1 -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_controller/config/joy_teleop.yaml: -------------------------------------------------------------------------------- 1 | joy_teleop: 2 | ros__parameters: 3 | move: 4 | type: topic 5 | interface_type: geometry_msgs/msg/TwistStamped 6 | topic_name: bumperbot_controller/cmd_vel 7 | deadman_buttons: [5] 8 | axis_mappings: 9 | twist-linear-x: 10 | axis: 1 11 | scale: 1.0 12 | offset: 0.0 13 | twist-angular-z: 14 | axis: 3 15 | scale: 8.0 16 | offset: 0.0 -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_cpp_examples/include/bumperbot_cpp_examples/simple_turtlesim_kinematics.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_TURTLESIM_KINEMATICS_HPP 2 | #define SIMPLE_TURTLESIM_KINEMATICS_HPP 3 | 4 | #include 5 | #include 6 | 7 | class SimpleTurtlesimKinematics : public rclcpp::Node 8 | { 9 | public: 10 | SimpleTurtlesimKinematics(const std::string& name); 11 | 12 | void turtle1PoseCallback(const turtlesim::msg::Pose& pose); 13 | 14 | void turtle2PoseCallback(const turtlesim::msg::Pose& pose); 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr turtle1_pose_sub_; 18 | rclcpp::Subscription::SharedPtr turtle2_pose_sub_; 19 | 20 | turtlesim::msg::Pose last_turtle1_pose_; 21 | turtlesim::msg::Pose last_turtle2_pose_; 22 | }; 23 | 24 | #endif // SIMPLE_TURTLESIM_KINEMATICS_HPP -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_cpp_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_cpp_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | rclcpp 12 | std_msgs 13 | rcl_interfaces 14 | turtlesim 15 | bumperbot_msgs 16 | geometry_msgs 17 | tf2 18 | tf2_ros 19 | 20 | ament_lint_auto 21 | ament_lint_common 22 | 23 | 24 | ament_cmake 25 | 26 | -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_publisher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | 7 | using namespace std::chrono_literals; 8 | 9 | class SimplePublisher : public rclcpp::Node 10 | { 11 | public: 12 | SimplePublisher() : Node("simple_publisher"), counter_(0) 13 | { 14 | pub_ = create_publisher("chatter", 10); 15 | timer_ = create_wall_timer(1s, std::bind(&SimplePublisher::timerCallback, this)); 16 | RCLCPP_INFO(get_logger(), "Publishing at 1 Hz"); 17 | } 18 | 19 | void timerCallback() 20 | { 21 | auto message = std_msgs::msg::String(); 22 | message.data = "Hello ROS 2 - counter:" + std::to_string(counter_++); 23 | pub_->publish(message); 24 | } 25 | 26 | private: 27 | rclcpp::Publisher::SharedPtr pub_; 28 | rclcpp::TimerBase::SharedPtr timer_; 29 | unsigned int counter_; 30 | }; 31 | 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | rclcpp::init(argc, argv); 36 | auto node = std::make_shared(); 37 | rclcpp::spin(node); 38 | rclcpp::shutdown(); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_subscriber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using std::placeholders::_1; 6 | 7 | class SimpleSubscriber : public rclcpp::Node 8 | { 9 | public: 10 | SimpleSubscriber() : Node("simple_subscriber") 11 | { 12 | sub_ = create_subscription( 13 | "chatter", 10, std::bind(&SimpleSubscriber::msgCallback, this, _1)); 14 | } 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr sub_; 18 | 19 | void msgCallback(const std_msgs::msg::String &msg) const 20 | { 21 | RCLCPP_INFO_STREAM(this->get_logger(), "I heard: " << msg.data.c_str()); 22 | } 23 | }; 24 | 25 | 26 | int main(int argc, char * argv[]) 27 | { 28 | rclcpp::init(argc, argv); 29 | rclcpp::spin(std::make_shared()); 30 | rclcpp::shutdown(); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(bumperbot_description) 3 | 4 | 5 | find_package(ament_cmake REQUIRED) 6 | find_package(urdf REQUIRED) 7 | 8 | install( 9 | DIRECTORY launch meshes urdf rviz 10 | DESTINATION share/${PROJECT_NAME} 11 | ) 12 | 13 | if(BUILD_TESTING) 14 | find_package(ament_lint_auto REQUIRED) 15 | ament_lint_auto_find_test_dependencies() 16 | endif() 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_description/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_description 5 | 0.0.0 6 | Bumperbot Description package 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | 12 | robot_state_publisher 13 | urdf 14 | joint_state_publisher_gui 15 | rviz2 16 | xacro 17 | ros2launch 18 | ros_gz_sim 19 | gz_ros2_control 20 | ign_ros2_control 21 | 22 | ament_lint_auto 23 | ament_lint_common 24 | 25 | 26 | ament_cmake 27 | 28 | -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_msgs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(bumperbot_msgs) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | find_package(ament_cmake REQUIRED) 9 | find_package(geometry_msgs REQUIRED) 10 | find_package(rosidl_default_generators REQUIRED) 11 | 12 | rosidl_generate_interfaces(${PROJECT_NAME} 13 | "srv/AddTwoInts.srv" 14 | "srv/GetTransform.srv" 15 | DEPENDENCIES geometry_msgs 16 | ) 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_msgs/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_msgs 5 | 0.0.0 6 | Definition of Interfaces for the bumperbot 7 | Antonio Brandi 8 | Apàche 2.0 9 | 10 | ament_cmake 11 | rosidl_default_generators 12 | 13 | geometry_msgs 14 | 15 | rosidl_default_runtime 16 | 17 | rosidl_interface_packages 18 | 19 | ament_lint_auto 20 | ament_lint_common 21 | 22 | 23 | ament_cmake 24 | 25 | -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_msgs/srv/AddTwoInts.srv: -------------------------------------------------------------------------------- 1 | # Request 2 | int64 a 3 | int64 b 4 | --- 5 | # Response 6 | int64 sum -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_msgs/srv/GetTransform.srv: -------------------------------------------------------------------------------- 1 | # Request 2 | string frame_id 3 | string child_frame_id 4 | --- 5 | # Response 6 | geometry_msgs/TransformStamped transform 7 | bool success -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_publisher.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimplePublisher(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_publisher") 10 | self.pub_ = self.create_publisher(String, "chatter", 10) 11 | self.counter_ = 0 12 | self.frequency_ = 1.0 13 | self.get_logger().info("Publishing at %d Hz" % self.frequency_) 14 | 15 | self.timer_ = self.create_timer(self.frequency_, self.timerCallback) 16 | 17 | def timerCallback(self): 18 | msg = String() 19 | msg.data = "Hello ROS 2 - counter: %d" % self.counter_ 20 | self.pub_.publish(msg) 21 | self.counter_ += 1 22 | 23 | 24 | def main(): 25 | rclpy.init() 26 | 27 | simple_publisher = SimplePublisher() 28 | rclpy.spin(simple_publisher) 29 | 30 | simple_publisher.destroy_node() 31 | rclpy.shutdown() 32 | 33 | 34 | if __name__ == '__main__': 35 | main() -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_service_server.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from bumperbot_msgs.srv import AddTwoInts 4 | 5 | 6 | class SimpleServiceServer(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_service_server") 10 | self.service_ = self.create_service(AddTwoInts, "add_two_ints", self.serviceCallback) 11 | self.get_logger().info("Service add_two_ints Ready") 12 | 13 | 14 | def serviceCallback(self, req, res): 15 | self.get_logger().info("New Request Received a: %d, b: %d" % (req.a, req.b)) 16 | res.sum = req.a + req.b 17 | self.get_logger().info("Returning sum: %d" % res.sum) 18 | return res 19 | 20 | 21 | def main(): 22 | rclpy.init() 23 | 24 | simple_service_server = SimpleServiceServer() 25 | rclpy.spin(simple_service_server) 26 | 27 | simple_service_server.destroy_node() 28 | rclpy.shutdown() 29 | 30 | 31 | if __name__ == '__main__': 32 | main() -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_subscriber.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimpleSubscriber(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_subscriber") 10 | self.sub_ = self.create_subscription(String, "chatter", self.msgCallback, 10) 11 | self.sub_ 12 | 13 | def msgCallback(self, msg): 14 | self.get_logger().info("I heard: %s" % msg.data) 15 | 16 | 17 | def main(): 18 | rclpy.init() 19 | 20 | simple_publisher = SimpleSubscriber() 21 | rclpy.spin(simple_publisher) 22 | 23 | simple_publisher.destroy_node() 24 | rclpy.shutdown() 25 | 26 | 27 | if __name__ == '__main__': 28 | main() -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_py_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_py_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | rclpy 11 | std_msgs 12 | rcl_interfaces 13 | turtlesim 14 | bumperbot_msgs 15 | tf2_ros 16 | geometry_msgs 17 | tf_transformations 18 | 19 | ament_copyright 20 | ament_flake8 21 | ament_pep257 22 | python3-pytest 23 | 24 | 25 | ament_python 26 | 27 | 28 | -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_py_examples/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/bumperbot_py_examples 3 | [install] 4 | install_scripts=$base/lib/bumperbot_py_examples 5 | -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_py_examples/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_py_examples/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /Section10_Probability_for_Robotics/bumperbot_ws/src/bumperbot_py_examples/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_controller/bumperbot_controller/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_controller/bumperbot_controller/__init__.py -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_controller/config/joy_config.yaml: -------------------------------------------------------------------------------- 1 | joystick: 2 | ros__parameters: 3 | device_id: 0 4 | device_name: "" 5 | deadzone: 0.5 6 | autorepeat_rate: 20.0 7 | sticky_buttons: false 8 | coalesce_interval_ms: 1 -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_controller/config/joy_teleop.yaml: -------------------------------------------------------------------------------- 1 | joy_teleop: 2 | ros__parameters: 3 | move: 4 | type: topic 5 | interface_type: geometry_msgs/msg/TwistStamped 6 | topic_name: bumperbot_controller/cmd_vel 7 | deadman_buttons: [5] 8 | axis_mappings: 9 | twist-linear-x: 10 | axis: 1 11 | scale: 1.0 12 | offset: 0.0 13 | twist-angular-z: 14 | axis: 3 15 | scale: 8.0 16 | offset: 0.0 -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_cpp_examples/include/bumperbot_cpp_examples/simple_turtlesim_kinematics.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_TURTLESIM_KINEMATICS_HPP 2 | #define SIMPLE_TURTLESIM_KINEMATICS_HPP 3 | 4 | #include 5 | #include 6 | 7 | class SimpleTurtlesimKinematics : public rclcpp::Node 8 | { 9 | public: 10 | SimpleTurtlesimKinematics(const std::string& name); 11 | 12 | void turtle1PoseCallback(const turtlesim::msg::Pose& pose); 13 | 14 | void turtle2PoseCallback(const turtlesim::msg::Pose& pose); 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr turtle1_pose_sub_; 18 | rclcpp::Subscription::SharedPtr turtle2_pose_sub_; 19 | 20 | turtlesim::msg::Pose last_turtle1_pose_; 21 | turtlesim::msg::Pose last_turtle2_pose_; 22 | }; 23 | 24 | #endif // SIMPLE_TURTLESIM_KINEMATICS_HPP -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_cpp_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_cpp_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | rclcpp 12 | std_msgs 13 | rcl_interfaces 14 | bumperbot_msgs 15 | geometry_msgs 16 | tf2 17 | tf2_ros 18 | turtlesim 19 | 20 | ament_lint_auto 21 | ament_lint_common 22 | 23 | 24 | ament_cmake 25 | 26 | -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_publisher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | 7 | using namespace std::chrono_literals; 8 | 9 | class SimplePublisher : public rclcpp::Node 10 | { 11 | public: 12 | SimplePublisher() : Node("simple_publisher"), counter_(0) 13 | { 14 | pub_ = create_publisher("chatter", 10); 15 | timer_ = create_wall_timer(1s, std::bind(&SimplePublisher::timerCallback, this)); 16 | RCLCPP_INFO(get_logger(), "Publishing at 1 Hz"); 17 | } 18 | 19 | void timerCallback() 20 | { 21 | auto message = std_msgs::msg::String(); 22 | message.data = "Hello ROS 2 - counter:" + std::to_string(counter_++); 23 | pub_->publish(message); 24 | } 25 | 26 | private: 27 | rclcpp::Publisher::SharedPtr pub_; 28 | rclcpp::TimerBase::SharedPtr timer_; 29 | unsigned int counter_; 30 | }; 31 | 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | rclcpp::init(argc, argv); 36 | auto node = std::make_shared(); 37 | rclcpp::spin(node); 38 | rclcpp::shutdown(); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_subscriber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using std::placeholders::_1; 6 | 7 | class SimpleSubscriber : public rclcpp::Node 8 | { 9 | public: 10 | SimpleSubscriber() : Node("simple_subscriber") 11 | { 12 | sub_ = create_subscription( 13 | "chatter", 10, std::bind(&SimpleSubscriber::msgCallback, this, _1)); 14 | } 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr sub_; 18 | 19 | void msgCallback(const std_msgs::msg::String &msg) const 20 | { 21 | RCLCPP_INFO_STREAM(this->get_logger(), "I heard: " << msg.data.c_str()); 22 | } 23 | }; 24 | 25 | 26 | int main(int argc, char * argv[]) 27 | { 28 | rclcpp::init(argc, argv); 29 | rclcpp::spin(std::make_shared()); 30 | rclcpp::shutdown(); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(bumperbot_description) 3 | 4 | 5 | find_package(ament_cmake REQUIRED) 6 | find_package(urdf REQUIRED) 7 | 8 | install( 9 | DIRECTORY launch meshes urdf rviz 10 | DESTINATION share/${PROJECT_NAME} 11 | ) 12 | 13 | if(BUILD_TESTING) 14 | find_package(ament_lint_auto REQUIRED) 15 | ament_lint_auto_find_test_dependencies() 16 | endif() 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_description/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_description 5 | 0.0.0 6 | Bumperbot Description package 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | 12 | robot_state_publisher 13 | urdf 14 | joint_state_publisher_gui 15 | rviz2 16 | xacro 17 | ros2launch 18 | ros_gz_sim 19 | ros_gz_bridge 20 | gz_ros2_control 21 | ign_ros2_control 22 | 23 | ament_lint_auto 24 | ament_lint_common 25 | 26 | 27 | ament_cmake 28 | 29 | -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_localization/bumperbot_localization/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_localization/bumperbot_localization/__init__.py -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_localization/bumperbot_localization/imu_republisher.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import rclpy 3 | import time 4 | from rclpy.node import Node 5 | from sensor_msgs.msg import Imu 6 | 7 | imu_pub = None 8 | 9 | def imuCallback(imu): 10 | global imu_pub 11 | imu.header.frame_id = "base_footprint_ekf" 12 | imu_pub.publish(imu) 13 | 14 | 15 | def main(args=None): 16 | global imu_pub 17 | rclpy.init(args=args) 18 | node = Node('imu_republisher_node') 19 | time.sleep(1) 20 | imu_pub = node.create_publisher(Imu, "imu_ekf", 10) 21 | imu_sub = node.create_subscription(Imu, "imu/out", imuCallback, 10) 22 | rclpy.spin(node) 23 | rclpy.shutdown() 24 | 25 | if __name__ == '__main__': 26 | main() 27 | -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_localization/include/bumperbot_localization/kalman_filter.hpp: -------------------------------------------------------------------------------- 1 | #ifndef KALMAN_FILTER_HPP 2 | #define KALMAN_FILTER_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class KalmanFilter : public rclcpp::Node 10 | { 11 | public: 12 | KalmanFilter(const std::string& name); 13 | 14 | void statePrediction(); 15 | 16 | void measurementUpdate(); 17 | 18 | 19 | private: 20 | void odomCallback(const nav_msgs::msg::Odometry &); 21 | 22 | void imuCallback(const sensor_msgs::msg::Imu &); 23 | 24 | 25 | rclcpp::Subscription::SharedPtr odom_sub_; 26 | rclcpp::Subscription::SharedPtr imu_sub_; 27 | rclcpp::Publisher::SharedPtr odom_pub_; 28 | double mean_; 29 | double variance_; 30 | double motion_variance_; 31 | double measurement_variance_; 32 | double motion_; 33 | bool is_first_odom_; 34 | double last_angular_z_; 35 | double imu_angular_z_; 36 | nav_msgs::msg::Odometry kalman_odom_; 37 | }; 38 | 39 | #endif // KALMAN_FILTER_HPP -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_localization/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_localization 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | ament_cmake_python 12 | 13 | rclcpp 14 | rclpy 15 | nav_msgs 16 | sensor_msgs 17 | 18 | robot_localization 19 | 20 | ament_lint_auto 21 | ament_lint_common 22 | 23 | 24 | ament_cmake 25 | 26 | 27 | -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_localization/src/imu_republisher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std::chrono_literals; 5 | 6 | rclcpp::Publisher::SharedPtr imu_pub; 7 | 8 | void imuCallback(const sensor_msgs::msg::Imu &imu) 9 | { 10 | sensor_msgs::msg::Imu new_imu; 11 | new_imu = imu; 12 | new_imu.header.frame_id = "base_footprint_ekf"; 13 | imu_pub->publish(new_imu); 14 | } 15 | 16 | 17 | int main(int argc, char **argv) 18 | { 19 | rclcpp::init(argc, argv); 20 | 21 | std::shared_ptr node = rclcpp::Node::make_shared("imu_republisher_node"); 22 | rclcpp::sleep_for(1s); 23 | imu_pub = node->create_publisher("imu_ekf", 10); 24 | auto imu_sub = node->create_subscription("imu/out", 10, imuCallback); 25 | 26 | rclcpp::spin(node); 27 | rclcpp::shutdown(); 28 | } -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_msgs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(bumperbot_msgs) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | find_package(ament_cmake REQUIRED) 9 | find_package(geometry_msgs REQUIRED) 10 | find_package(rosidl_default_generators REQUIRED) 11 | 12 | rosidl_generate_interfaces(${PROJECT_NAME} 13 | "srv/AddTwoInts.srv" 14 | "srv/GetTransform.srv" 15 | DEPENDENCIES geometry_msgs 16 | ) 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_msgs/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_msgs 5 | 0.0.0 6 | Definition of Interfaces for the bumperbot 7 | Antonio Brandi 8 | Apàche 2.0 9 | 10 | ament_cmake 11 | rosidl_default_generators 12 | 13 | geometry_msgs 14 | 15 | rosidl_default_runtime 16 | 17 | rosidl_interface_packages 18 | 19 | ament_lint_auto 20 | ament_lint_common 21 | 22 | 23 | ament_cmake 24 | 25 | -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_msgs/srv/AddTwoInts.srv: -------------------------------------------------------------------------------- 1 | # Request 2 | int64 a 3 | int64 b 4 | --- 5 | # Response 6 | int64 sum -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_msgs/srv/GetTransform.srv: -------------------------------------------------------------------------------- 1 | # Request 2 | string frame_id 3 | string child_frame_id 4 | --- 5 | # Response 6 | geometry_msgs/TransformStamped transform 7 | bool success -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_publisher.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimplePublisher(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_publisher") 10 | self.pub_ = self.create_publisher(String, "chatter", 10) 11 | self.counter_ = 0 12 | self.frequency_ = 1.0 13 | self.get_logger().info("Publishing at %d Hz" % self.frequency_) 14 | 15 | self.timer_ = self.create_timer(self.frequency_, self.timerCallback) 16 | 17 | def timerCallback(self): 18 | msg = String() 19 | msg.data = "Hello ROS 2 - counter: %d" % self.counter_ 20 | self.pub_.publish(msg) 21 | self.counter_ += 1 22 | 23 | 24 | def main(): 25 | rclpy.init() 26 | 27 | simple_publisher = SimplePublisher() 28 | rclpy.spin(simple_publisher) 29 | 30 | simple_publisher.destroy_node() 31 | rclpy.shutdown() 32 | 33 | 34 | if __name__ == '__main__': 35 | main() -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_service_server.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from bumperbot_msgs.srv import AddTwoInts 4 | 5 | 6 | class SimpleServiceServer(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_service_server") 10 | self.service_ = self.create_service(AddTwoInts, "add_two_ints", self.serviceCallback) 11 | self.get_logger().info("Service add_two_ints Ready") 12 | 13 | 14 | def serviceCallback(self, req, res): 15 | self.get_logger().info("New Request Received a: %d, b: %d" % (req.a, req.b)) 16 | res.sum = req.a + req.b 17 | self.get_logger().info("Returning sum: %d" % res.sum) 18 | return res 19 | 20 | 21 | def main(): 22 | rclpy.init() 23 | 24 | simple_service_server = SimpleServiceServer() 25 | rclpy.spin(simple_service_server) 26 | 27 | simple_service_server.destroy_node() 28 | rclpy.shutdown() 29 | 30 | 31 | if __name__ == '__main__': 32 | main() -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_subscriber.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimpleSubscriber(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_subscriber") 10 | self.sub_ = self.create_subscription(String, "chatter", self.msgCallback, 10) 11 | self.sub_ 12 | 13 | def msgCallback(self, msg): 14 | self.get_logger().info("I heard: %s" % msg.data) 15 | 16 | 17 | def main(): 18 | rclpy.init() 19 | 20 | simple_publisher = SimpleSubscriber() 21 | rclpy.spin(simple_publisher) 22 | 23 | simple_publisher.destroy_node() 24 | rclpy.shutdown() 25 | 26 | 27 | if __name__ == '__main__': 28 | main() -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_py_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_py_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | rclpy 11 | std_msgs 12 | rcl_interfaces 13 | bumperbot_msgs 14 | tf2_ros 15 | geometry_msgs 16 | tf_transformations 17 | turtlesim 18 | 19 | ament_copyright 20 | ament_flake8 21 | ament_pep257 22 | python3-pytest 23 | 24 | 25 | ament_python 26 | 27 | 28 | -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_py_examples/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/bumperbot_py_examples 3 | [install] 4 | install_scripts=$base/lib/bumperbot_py_examples 5 | -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_py_examples/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_py_examples/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /Section11_Sensor_Fusion/bumperbot_ws/src/bumperbot_py_examples/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_bringup/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(bumperbot_bringup) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | find_package(ament_cmake REQUIRED) 9 | 10 | install( 11 | DIRECTORY launch 12 | DESTINATION share/${PROJECT_NAME} 13 | ) 14 | 15 | ament_package() 16 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_bringup/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_bringup 5 | 0.0.0 6 | Bumperbot Bringup package 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | 12 | ament_lint_auto 13 | ament_lint_common 14 | 15 | 16 | ament_cmake 17 | 18 | 19 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_controller/bumperbot_controller/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_controller/bumperbot_controller/__init__.py -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_controller/config/joy_config.yaml: -------------------------------------------------------------------------------- 1 | joystick: 2 | ros__parameters: 3 | device_id: 0 4 | device_name: "" 5 | deadzone: 0.5 6 | autorepeat_rate: 20.0 7 | sticky_buttons: false 8 | coalesce_interval_ms: 1 -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_controller/config/joy_teleop.yaml: -------------------------------------------------------------------------------- 1 | joy_teleop: 2 | ros__parameters: 3 | move: 4 | type: topic 5 | interface_type: geometry_msgs/msg/TwistStamped 6 | topic_name: bumperbot_controller/cmd_vel 7 | deadman_buttons: [5] 8 | axis_mappings: 9 | twist-linear-x: 10 | axis: 1 11 | scale: 1.0 12 | offset: 0.0 13 | twist-angular-z: 14 | axis: 3 15 | scale: 8.0 16 | offset: 0.0 -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_cpp_examples/include/bumperbot_cpp_examples/simple_turtlesim_kinematics.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_TURTLESIM_KINEMATICS_HPP 2 | #define SIMPLE_TURTLESIM_KINEMATICS_HPP 3 | 4 | #include 5 | #include 6 | 7 | class SimpleTurtlesimKinematics : public rclcpp::Node 8 | { 9 | public: 10 | SimpleTurtlesimKinematics(const std::string& name); 11 | 12 | void turtle1PoseCallback(const turtlesim::msg::Pose& pose); 13 | 14 | void turtle2PoseCallback(const turtlesim::msg::Pose& pose); 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr turtle1_pose_sub_; 18 | rclcpp::Subscription::SharedPtr turtle2_pose_sub_; 19 | 20 | turtlesim::msg::Pose last_turtle1_pose_; 21 | turtlesim::msg::Pose last_turtle2_pose_; 22 | }; 23 | 24 | #endif // SIMPLE_TURTLESIM_KINEMATICS_HPP -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_cpp_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_cpp_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | rclcpp 12 | std_msgs 13 | rcl_interfaces 14 | bumperbot_msgs 15 | geometry_msgs 16 | tf2 17 | tf2_ros 18 | turtlesim 19 | rclcpp_lifecycle 20 | 21 | ament_lint_auto 22 | ament_lint_common 23 | 24 | 25 | ament_cmake 26 | 27 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_publisher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | 7 | using namespace std::chrono_literals; 8 | 9 | class SimplePublisher : public rclcpp::Node 10 | { 11 | public: 12 | SimplePublisher() : Node("simple_publisher"), counter_(0) 13 | { 14 | pub_ = create_publisher("chatter", 10); 15 | timer_ = create_wall_timer(1s, std::bind(&SimplePublisher::timerCallback, this)); 16 | RCLCPP_INFO(get_logger(), "Publishing at 1 Hz"); 17 | } 18 | 19 | void timerCallback() 20 | { 21 | auto message = std_msgs::msg::String(); 22 | message.data = "Hello ROS 2 - counter:" + std::to_string(counter_++); 23 | pub_->publish(message); 24 | } 25 | 26 | private: 27 | rclcpp::Publisher::SharedPtr pub_; 28 | rclcpp::TimerBase::SharedPtr timer_; 29 | unsigned int counter_; 30 | }; 31 | 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | rclcpp::init(argc, argv); 36 | auto node = std::make_shared(); 37 | rclcpp::spin(node); 38 | rclcpp::shutdown(); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_subscriber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using std::placeholders::_1; 6 | 7 | class SimpleSubscriber : public rclcpp::Node 8 | { 9 | public: 10 | SimpleSubscriber() : Node("simple_subscriber") 11 | { 12 | sub_ = create_subscription( 13 | "chatter", 10, std::bind(&SimpleSubscriber::msgCallback, this, _1)); 14 | } 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr sub_; 18 | 19 | void msgCallback(const std_msgs::msg::String &msg) const 20 | { 21 | RCLCPP_INFO_STREAM(this->get_logger(), "I heard: " << msg.data.c_str()); 22 | } 23 | }; 24 | 25 | 26 | int main(int argc, char * argv[]) 27 | { 28 | rclcpp::init(argc, argv); 29 | rclcpp::spin(std::make_shared()); 30 | rclcpp::shutdown(); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(bumperbot_description) 3 | 4 | 5 | find_package(ament_cmake REQUIRED) 6 | find_package(urdf REQUIRED) 7 | 8 | install( 9 | DIRECTORY launch meshes urdf rviz 10 | DESTINATION share/${PROJECT_NAME} 11 | ) 12 | 13 | if(BUILD_TESTING) 14 | find_package(ament_lint_auto REQUIRED) 15 | ament_lint_auto_find_test_dependencies() 16 | endif() 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_description/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_description 5 | 0.0.0 6 | Bumperbot Description package 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | 12 | robot_state_publisher 13 | urdf 14 | joint_state_publisher_gui 15 | rviz2 16 | xacro 17 | ros2launch 18 | ros_gz_sim 19 | ros_gz_bridge 20 | gz_ros2_control 21 | ign_ros2_control 22 | 23 | ament_lint_auto 24 | ament_lint_common 25 | 26 | 27 | ament_cmake 28 | 29 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_firmware/bumperbot_firmware/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_firmware/bumperbot_firmware/__init__.py -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_firmware/bumperbot_interface.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Bumperbot Hardware Interface 8 | 9 | 10 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_firmware/firmware/simple_motor_control/simple_motor_control.ino: -------------------------------------------------------------------------------- 1 | // L298N H-Bridge Connection PINs 2 | #define L298N_enA 9 // PWM 3 | #define L298N_in2 13 // Dir Motor A 4 | #define L298N_in1 12 // Dir Motor A 5 | 6 | float cmd = 0; 7 | 8 | void setup() { 9 | // Set pin modes 10 | pinMode(L298N_enA, OUTPUT); 11 | pinMode(L298N_in1, OUTPUT); 12 | pinMode(L298N_in2, OUTPUT); 13 | 14 | // Set Motor Rotation Direction 15 | digitalWrite(L298N_in1, HIGH); 16 | digitalWrite(L298N_in2, LOW); 17 | 18 | Serial.begin(115200); 19 | } 20 | 21 | void loop() { 22 | if (Serial.available()) 23 | { 24 | cmd = Serial.readString().toFloat(); 25 | } 26 | analogWrite(L298N_enA, cmd*100); 27 | } -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_firmware/firmware/simple_serial_receiver/simple_serial_receiver.ino: -------------------------------------------------------------------------------- 1 | #define LED_PIN 13 2 | 3 | void setup() { 4 | pinMode(LED_PIN, OUTPUT); 5 | digitalWrite(LED_PIN, LOW); 6 | 7 | Serial.begin(115200); 8 | Serial.setTimeout(1); 9 | } 10 | 11 | void loop() { 12 | if (Serial.available()) 13 | { 14 | int x = Serial.readString().toInt(); 15 | if(x == 0) 16 | { 17 | // turn off the led 18 | digitalWrite(LED_PIN, LOW); 19 | } 20 | else 21 | { 22 | // turn on the led 23 | digitalWrite(LED_PIN, HIGH); 24 | } 25 | } 26 | delay(0.1); 27 | } -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_firmware/firmware/simple_serial_transmitter/simple_serial_transmitter.ino: -------------------------------------------------------------------------------- 1 | int x = 0; 2 | 3 | void setup() { 4 | Serial.begin(115200); 5 | Serial.setTimeout(1); 6 | } 7 | 8 | void loop() { 9 | Serial.println(x); 10 | x++; 11 | delay(0.1); 12 | } -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_firmware/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_firmware 5 | 0.0.0 6 | The bumperbot_firmware package 7 | Antonio Brandi 8 | Apache 2.0 9 | Antonio Brandi 10 | 11 | ament_cmake 12 | ament_cmake_python 13 | rclcpp 14 | rclpy 15 | std_msgs 16 | hardware_interface 17 | rclcpp_lifecycle 18 | pluginlib 19 | libserial-dev 20 | 21 | python3-serial 22 | python3-smbus 23 | 24 | ament_lint_auto 25 | ament_lint_common 26 | 27 | 28 | ament_cmake 29 | 30 | 31 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_localization/bumperbot_localization/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_localization/bumperbot_localization/__init__.py -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_localization/bumperbot_localization/imu_republisher.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import rclpy 3 | import time 4 | from rclpy.node import Node 5 | from sensor_msgs.msg import Imu 6 | 7 | imu_pub = None 8 | 9 | def imuCallback(imu): 10 | global imu_pub 11 | imu.header.frame_id = "base_footprint_ekf" 12 | imu_pub.publish(imu) 13 | 14 | 15 | def main(args=None): 16 | global imu_pub 17 | rclpy.init(args=args) 18 | node = Node('imu_republisher_node') 19 | time.sleep(1) 20 | imu_pub = node.create_publisher(Imu, "imu_ekf", 10) 21 | imu_sub = node.create_subscription(Imu, "imu/out", imuCallback, 10) 22 | rclpy.spin(node) 23 | rclpy.shutdown() 24 | 25 | if __name__ == '__main__': 26 | main() 27 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_localization/include/bumperbot_localization/kalman_filter.hpp: -------------------------------------------------------------------------------- 1 | #ifndef KALMAN_FILTER_HPP 2 | #define KALMAN_FILTER_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class KalmanFilter : public rclcpp::Node 10 | { 11 | public: 12 | KalmanFilter(const std::string& name); 13 | 14 | void statePrediction(); 15 | 16 | void measurementUpdate(); 17 | 18 | 19 | private: 20 | void odomCallback(const nav_msgs::msg::Odometry &); 21 | 22 | void imuCallback(const sensor_msgs::msg::Imu &); 23 | 24 | 25 | rclcpp::Subscription::SharedPtr odom_sub_; 26 | rclcpp::Subscription::SharedPtr imu_sub_; 27 | rclcpp::Publisher::SharedPtr odom_pub_; 28 | double mean_; 29 | double variance_; 30 | double motion_variance_; 31 | double measurement_variance_; 32 | double motion_; 33 | bool is_first_odom_; 34 | double last_angular_z_; 35 | double imu_angular_z_; 36 | nav_msgs::msg::Odometry kalman_odom_; 37 | }; 38 | 39 | #endif // KALMAN_FILTER_HPP -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_localization/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_localization 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | ament_cmake_python 12 | 13 | rclcpp 14 | rclpy 15 | nav_msgs 16 | sensor_msgs 17 | 18 | robot_localization 19 | 20 | ament_lint_auto 21 | ament_lint_common 22 | 23 | 24 | ament_cmake 25 | 26 | 27 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_localization/src/imu_republisher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std::chrono_literals; 5 | 6 | rclcpp::Publisher::SharedPtr imu_pub; 7 | 8 | void imuCallback(const sensor_msgs::msg::Imu &imu) 9 | { 10 | sensor_msgs::msg::Imu new_imu; 11 | new_imu = imu; 12 | new_imu.header.frame_id = "base_footprint_ekf"; 13 | imu_pub->publish(new_imu); 14 | } 15 | 16 | 17 | int main(int argc, char **argv) 18 | { 19 | rclcpp::init(argc, argv); 20 | 21 | std::shared_ptr node = rclcpp::Node::make_shared("imu_republisher_node"); 22 | rclcpp::sleep_for(1s); 23 | imu_pub = node->create_publisher("imu_ekf", 10); 24 | auto imu_sub = node->create_subscription("imu/out", 10, imuCallback); 25 | 26 | rclcpp::spin(node); 27 | rclcpp::shutdown(); 28 | } -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_msgs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(bumperbot_msgs) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | find_package(ament_cmake REQUIRED) 9 | find_package(geometry_msgs REQUIRED) 10 | find_package(rosidl_default_generators REQUIRED) 11 | 12 | rosidl_generate_interfaces(${PROJECT_NAME} 13 | "srv/AddTwoInts.srv" 14 | "srv/GetTransform.srv" 15 | DEPENDENCIES geometry_msgs 16 | ) 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_msgs/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_msgs 5 | 0.0.0 6 | Definition of Interfaces for the bumperbot 7 | Antonio Brandi 8 | Apàche 2.0 9 | 10 | ament_cmake 11 | rosidl_default_generators 12 | 13 | geometry_msgs 14 | 15 | rosidl_default_runtime 16 | 17 | rosidl_interface_packages 18 | 19 | ament_lint_auto 20 | ament_lint_common 21 | 22 | 23 | ament_cmake 24 | 25 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_msgs/srv/AddTwoInts.srv: -------------------------------------------------------------------------------- 1 | # Request 2 | int64 a 3 | int64 b 4 | --- 5 | # Response 6 | int64 sum -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_msgs/srv/GetTransform.srv: -------------------------------------------------------------------------------- 1 | # Request 2 | string frame_id 3 | string child_frame_id 4 | --- 5 | # Response 6 | geometry_msgs/TransformStamped transform 7 | bool success -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_publisher.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimplePublisher(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_publisher") 10 | self.pub_ = self.create_publisher(String, "chatter", 10) 11 | self.counter_ = 0 12 | self.frequency_ = 1.0 13 | self.get_logger().info("Publishing at %d Hz" % self.frequency_) 14 | 15 | self.timer_ = self.create_timer(self.frequency_, self.timerCallback) 16 | 17 | def timerCallback(self): 18 | msg = String() 19 | msg.data = "Hello ROS 2 - counter: %d" % self.counter_ 20 | self.pub_.publish(msg) 21 | self.counter_ += 1 22 | 23 | 24 | def main(): 25 | rclpy.init() 26 | 27 | simple_publisher = SimplePublisher() 28 | rclpy.spin(simple_publisher) 29 | 30 | simple_publisher.destroy_node() 31 | rclpy.shutdown() 32 | 33 | 34 | if __name__ == '__main__': 35 | main() -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_service_server.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from bumperbot_msgs.srv import AddTwoInts 4 | 5 | 6 | class SimpleServiceServer(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_service_server") 10 | self.service_ = self.create_service(AddTwoInts, "add_two_ints", self.serviceCallback) 11 | self.get_logger().info("Service add_two_ints Ready") 12 | 13 | 14 | def serviceCallback(self, req, res): 15 | self.get_logger().info("New Request Received a: %d, b: %d" % (req.a, req.b)) 16 | res.sum = req.a + req.b 17 | self.get_logger().info("Returning sum: %d" % res.sum) 18 | return res 19 | 20 | 21 | def main(): 22 | rclpy.init() 23 | 24 | simple_service_server = SimpleServiceServer() 25 | rclpy.spin(simple_service_server) 26 | 27 | simple_service_server.destroy_node() 28 | rclpy.shutdown() 29 | 30 | 31 | if __name__ == '__main__': 32 | main() -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_subscriber.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimpleSubscriber(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_subscriber") 10 | self.sub_ = self.create_subscription(String, "chatter", self.msgCallback, 10) 11 | self.sub_ 12 | 13 | def msgCallback(self, msg): 14 | self.get_logger().info("I heard: %s" % msg.data) 15 | 16 | 17 | def main(): 18 | rclpy.init() 19 | 20 | simple_publisher = SimpleSubscriber() 21 | rclpy.spin(simple_publisher) 22 | 23 | simple_publisher.destroy_node() 24 | rclpy.shutdown() 25 | 26 | 27 | if __name__ == '__main__': 28 | main() -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_py_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_py_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | rclpy 11 | std_msgs 12 | rcl_interfaces 13 | bumperbot_msgs 14 | tf2_ros 15 | geometry_msgs 16 | tf_transformations 17 | turtlesim 18 | 19 | ament_copyright 20 | ament_flake8 21 | ament_pep257 22 | python3-pytest 23 | 24 | 25 | ament_python 26 | 27 | 28 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_py_examples/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/bumperbot_py_examples 3 | [install] 4 | install_scripts=$base/lib/bumperbot_py_examples 5 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_py_examples/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_py_examples/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /Section12_Build_the_Robot/bumperbot_ws/src/bumperbot_py_examples/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_cpp_examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(bumperbot_cpp_examples) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | find_package(ament_cmake REQUIRED) 9 | find_package(rclcpp REQUIRED) 10 | find_package(std_msgs REQUIRED) 11 | 12 | add_executable(simple_publisher src/simple_publisher.cpp) 13 | ament_target_dependencies(simple_publisher rclcpp std_msgs) 14 | 15 | add_executable(simple_subscriber src/simple_subscriber.cpp) 16 | ament_target_dependencies(simple_subscriber rclcpp std_msgs) 17 | 18 | install(TARGETS 19 | simple_publisher 20 | simple_subscriber 21 | DESTINATION lib/${PROJECT_NAME} 22 | ) 23 | 24 | ament_package() -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_cpp_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_cpp_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | rclcpp 12 | std_msgs 13 | 14 | ament_lint_auto 15 | ament_lint_common 16 | 17 | 18 | ament_cmake 19 | 20 | -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_publisher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | 7 | using namespace std::chrono_literals; 8 | 9 | class SimplePublisher : public rclcpp::Node 10 | { 11 | public: 12 | SimplePublisher() : Node("simple_publisher"), counter_(0) 13 | { 14 | pub_ = create_publisher("chatter", 10); 15 | timer_ = create_wall_timer(1s, std::bind(&SimplePublisher::timerCallback, this)); 16 | RCLCPP_INFO(get_logger(), "Publishing at 1 Hz"); 17 | } 18 | 19 | void timerCallback() 20 | { 21 | auto message = std_msgs::msg::String(); 22 | message.data = "Hello ROS 2 - counter:" + std::to_string(counter_++); 23 | pub_->publish(message); 24 | } 25 | 26 | private: 27 | rclcpp::Publisher::SharedPtr pub_; 28 | rclcpp::TimerBase::SharedPtr timer_; 29 | unsigned int counter_; 30 | }; 31 | 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | rclcpp::init(argc, argv); 36 | auto node = std::make_shared(); 37 | rclcpp::spin(node); 38 | rclcpp::shutdown(); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_subscriber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using std::placeholders::_1; 6 | 7 | class SimpleSubscriber : public rclcpp::Node 8 | { 9 | public: 10 | SimpleSubscriber() : Node("simple_subscriber") 11 | { 12 | sub_ = create_subscription( 13 | "chatter", 10, std::bind(&SimpleSubscriber::msgCallback, this, _1)); 14 | } 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr sub_; 18 | 19 | void msgCallback(const std_msgs::msg::String &msg) const 20 | { 21 | RCLCPP_INFO_STREAM(this->get_logger(), "I heard: " << msg.data.c_str()); 22 | } 23 | }; 24 | 25 | 26 | int main(int argc, char * argv[]) 27 | { 28 | rclcpp::init(argc, argv); 29 | rclcpp::spin(std::make_shared()); 30 | rclcpp::shutdown(); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_publisher.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimplePublisher(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_publisher") 10 | self.pub_ = self.create_publisher(String, "chatter", 10) 11 | self.counter_ = 0 12 | self.frequency_ = 1.0 13 | self.get_logger().info("Publishing at %d Hz" % self.frequency_) 14 | 15 | self.timer_ = self.create_timer(self.frequency_, self.timerCallback) 16 | 17 | def timerCallback(self): 18 | msg = String() 19 | msg.data = "Hello ROS 2 - counter: %d" % self.counter_ 20 | self.pub_.publish(msg) 21 | self.counter_ += 1 22 | 23 | 24 | def main(): 25 | rclpy.init() 26 | 27 | simple_publisher = SimplePublisher() 28 | rclpy.spin(simple_publisher) 29 | 30 | simple_publisher.destroy_node() 31 | rclpy.shutdown() 32 | 33 | 34 | if __name__ == '__main__': 35 | main() -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_subscriber.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimpleSubscriber(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_subscriber") 10 | self.sub_ = self.create_subscription(String, "chatter", self.msgCallback, 10) 11 | self.sub_ 12 | 13 | def msgCallback(self, msg): 14 | self.get_logger().info("I heard: %s" % msg.data) 15 | 16 | 17 | def main(): 18 | rclpy.init() 19 | 20 | simple_publisher = SimpleSubscriber() 21 | rclpy.spin(simple_publisher) 22 | 23 | simple_publisher.destroy_node() 24 | rclpy.shutdown() 25 | 26 | 27 | if __name__ == '__main__': 28 | main() -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_py_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_py_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | rclpy 11 | std_msgs 12 | 13 | ament_copyright 14 | ament_flake8 15 | ament_pep257 16 | python3-pytest 17 | 18 | 19 | ament_python 20 | 21 | 22 | -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_py_examples/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/bumperbot_py_examples 3 | [install] 4 | install_scripts=$base/lib/bumperbot_py_examples 5 | -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_py_examples/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | package_name = 'bumperbot_py_examples' 4 | 5 | setup( 6 | name=package_name, 7 | version='0.0.0', 8 | packages=[package_name], 9 | data_files=[ 10 | ('share/ament_index/resource_index/packages', 11 | ['resource/' + package_name]), 12 | ('share/' + package_name, ['package.xml']), 13 | ], 14 | install_requires=['setuptools'], 15 | zip_safe=True, 16 | maintainer='user', 17 | maintainer_email='antonio.brandi@outlook.it', 18 | description='ROS 2 Code Examples', 19 | license='Apache 2.0', 20 | tests_require=['pytest'], 21 | entry_points={ 22 | 'console_scripts': [ 23 | 'simple_publisher = bumperbot_py_examples.simple_publisher:main', 24 | 'simple_subscriber = bumperbot_py_examples.simple_subscriber:main', 25 | ], 26 | }, 27 | ) -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_py_examples/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_py_examples/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /Section3_Introduction_to_ROS_2/bumperbot_ws/src/bumperbot_py_examples/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_cpp_examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(bumperbot_cpp_examples) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | find_package(ament_cmake REQUIRED) 9 | find_package(rclcpp REQUIRED) 10 | find_package(std_msgs REQUIRED) 11 | find_package(rcl_interfaces REQUIRED) 12 | 13 | add_executable(simple_publisher src/simple_publisher.cpp) 14 | ament_target_dependencies(simple_publisher rclcpp std_msgs) 15 | 16 | add_executable(simple_subscriber src/simple_subscriber.cpp) 17 | ament_target_dependencies(simple_subscriber rclcpp std_msgs) 18 | 19 | add_executable(simple_parameter src/simple_parameter.cpp) 20 | ament_target_dependencies(simple_parameter rclcpp rcl_interfaces) 21 | 22 | 23 | install(TARGETS 24 | simple_publisher 25 | simple_subscriber 26 | simple_parameter 27 | DESTINATION lib/${PROJECT_NAME} 28 | ) 29 | 30 | ament_package() -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_cpp_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_cpp_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | rclcpp 12 | std_msgs 13 | rcl_interfaces 14 | 15 | ament_lint_auto 16 | ament_lint_common 17 | 18 | 19 | ament_cmake 20 | 21 | -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_publisher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | 7 | using namespace std::chrono_literals; 8 | 9 | class SimplePublisher : public rclcpp::Node 10 | { 11 | public: 12 | SimplePublisher() : Node("simple_publisher"), counter_(0) 13 | { 14 | pub_ = create_publisher("chatter", 10); 15 | timer_ = create_wall_timer(1s, std::bind(&SimplePublisher::timerCallback, this)); 16 | RCLCPP_INFO(get_logger(), "Publishing at 1 Hz"); 17 | } 18 | 19 | void timerCallback() 20 | { 21 | auto message = std_msgs::msg::String(); 22 | message.data = "Hello ROS 2 - counter:" + std::to_string(counter_++); 23 | pub_->publish(message); 24 | } 25 | 26 | private: 27 | rclcpp::Publisher::SharedPtr pub_; 28 | rclcpp::TimerBase::SharedPtr timer_; 29 | unsigned int counter_; 30 | }; 31 | 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | rclcpp::init(argc, argv); 36 | auto node = std::make_shared(); 37 | rclcpp::spin(node); 38 | rclcpp::shutdown(); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_subscriber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using std::placeholders::_1; 6 | 7 | class SimpleSubscriber : public rclcpp::Node 8 | { 9 | public: 10 | SimpleSubscriber() : Node("simple_subscriber") 11 | { 12 | sub_ = create_subscription( 13 | "chatter", 10, std::bind(&SimpleSubscriber::msgCallback, this, _1)); 14 | } 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr sub_; 18 | 19 | void msgCallback(const std_msgs::msg::String &msg) const 20 | { 21 | RCLCPP_INFO_STREAM(this->get_logger(), "I heard: " << msg.data.c_str()); 22 | } 23 | }; 24 | 25 | 26 | int main(int argc, char * argv[]) 27 | { 28 | rclcpp::init(argc, argv); 29 | rclcpp::spin(std::make_shared()); 30 | rclcpp::shutdown(); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_description/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(bumperbot_description) 3 | 4 | 5 | find_package(ament_cmake REQUIRED) 6 | find_package(urdf REQUIRED) 7 | 8 | install( 9 | DIRECTORY launch meshes urdf rviz 10 | DESTINATION share/${PROJECT_NAME} 11 | ) 12 | 13 | if(BUILD_TESTING) 14 | find_package(ament_lint_auto REQUIRED) 15 | ament_lint_auto_find_test_dependencies() 16 | endif() 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section4_Locomotion/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section4_Locomotion/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section4_Locomotion/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section4_Locomotion/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section4_Locomotion/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section4_Locomotion/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_description/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_description 5 | 0.0.0 6 | Bumperbot Description package 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | 12 | robot_state_publisher 13 | urdf 14 | joint_state_publisher_gui 15 | rviz2 16 | xacro 17 | ros2launch 18 | ros_gz_sim 19 | 20 | ament_lint_auto 21 | ament_lint_common 22 | 23 | 24 | ament_cmake 25 | 26 | -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section4_Locomotion/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_publisher.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimplePublisher(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_publisher") 10 | self.pub_ = self.create_publisher(String, "chatter", 10) 11 | self.counter_ = 0 12 | self.frequency_ = 1.0 13 | self.get_logger().info("Publishing at %d Hz" % self.frequency_) 14 | 15 | self.timer_ = self.create_timer(self.frequency_, self.timerCallback) 16 | 17 | def timerCallback(self): 18 | msg = String() 19 | msg.data = "Hello ROS 2 - counter: %d" % self.counter_ 20 | self.pub_.publish(msg) 21 | self.counter_ += 1 22 | 23 | 24 | def main(): 25 | rclpy.init() 26 | 27 | simple_publisher = SimplePublisher() 28 | rclpy.spin(simple_publisher) 29 | 30 | simple_publisher.destroy_node() 31 | rclpy.shutdown() 32 | 33 | 34 | if __name__ == '__main__': 35 | main() -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_subscriber.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimpleSubscriber(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_subscriber") 10 | self.sub_ = self.create_subscription(String, "chatter", self.msgCallback, 10) 11 | self.sub_ 12 | 13 | def msgCallback(self, msg): 14 | self.get_logger().info("I heard: %s" % msg.data) 15 | 16 | 17 | def main(): 18 | rclpy.init() 19 | 20 | simple_publisher = SimpleSubscriber() 21 | rclpy.spin(simple_publisher) 22 | 23 | simple_publisher.destroy_node() 24 | rclpy.shutdown() 25 | 26 | 27 | if __name__ == '__main__': 28 | main() -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_py_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_py_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | rclpy 11 | std_msgs 12 | rcl_interfaces 13 | 14 | ament_copyright 15 | ament_flake8 16 | ament_pep257 17 | python3-pytest 18 | 19 | 20 | ament_python 21 | 22 | 23 | -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section4_Locomotion/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_py_examples/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/bumperbot_py_examples 3 | [install] 4 | install_scripts=$base/lib/bumperbot_py_examples 5 | -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_py_examples/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | package_name = 'bumperbot_py_examples' 4 | 5 | setup( 6 | name=package_name, 7 | version='0.0.0', 8 | packages=[package_name], 9 | data_files=[ 10 | ('share/ament_index/resource_index/packages', 11 | ['resource/' + package_name]), 12 | ('share/' + package_name, ['package.xml']), 13 | ], 14 | install_requires=['setuptools'], 15 | zip_safe=True, 16 | maintainer='user', 17 | maintainer_email='antonio.brandi@outlook.it', 18 | description='ROS 2 Code Examples', 19 | license='Apache 2.0', 20 | tests_require=['pytest'], 21 | entry_points={ 22 | 'console_scripts': [ 23 | 'simple_publisher = bumperbot_py_examples.simple_publisher:main', 24 | 'simple_subscriber = bumperbot_py_examples.simple_subscriber:main', 25 | 'simple_parameter = bumperbot_py_examples.simple_parameter:main', 26 | ], 27 | }, 28 | ) -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_py_examples/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_py_examples/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /Section4_Locomotion/bumperbot_ws/src/bumperbot_py_examples/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_controller/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(bumperbot_controller) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | 6 | install( 7 | DIRECTORY launch config 8 | DESTINATION share/${PROJECT_NAME} 9 | ) 10 | 11 | ament_package() -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_controller/config/bumperbot_controllers.yaml: -------------------------------------------------------------------------------- 1 | controller_manager: 2 | ros__parameters: 3 | update_rate: 100 # Hz 4 | use_sim_time: true 5 | 6 | joint_state_broadcaster: 7 | type: joint_state_broadcaster/JointStateBroadcaster 8 | 9 | simple_velocity_controller: 10 | type: velocity_controllers/JointGroupVelocityController 11 | 12 | 13 | simple_velocity_controller: 14 | ros__parameters: 15 | joints: 16 | - wheel_left_joint 17 | - wheel_right_joint -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_controller/launch/controller.launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | from launch import LaunchDescription 3 | from launch_ros.actions import Node 4 | 5 | 6 | def generate_launch_description(): 7 | 8 | joint_state_broadcaster_spawner = Node( 9 | package="controller_manager", 10 | executable="spawner", 11 | arguments=[ 12 | "joint_state_broadcaster", 13 | "--controller-manager", 14 | "/controller_manager", 15 | ], 16 | ) 17 | 18 | simple_controller = Node( 19 | package="controller_manager", 20 | executable="spawner", 21 | arguments=["simple_velocity_controller", 22 | "--controller-manager", 23 | "/controller_manager" 24 | ] 25 | ) 26 | 27 | return LaunchDescription( 28 | [ 29 | joint_state_broadcaster_spawner, 30 | simple_controller, 31 | ] 32 | ) -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_controller/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | bumperbot_controller 4 | 0.0.0 5 | The bumperbot_controller package 6 | Antonio Brandi 7 | Apache 2.0 8 | Antonio Brandi 9 | 10 | ament_cmake 11 | 12 | ros2launch 13 | robot_state_publisher 14 | xacro 15 | controller_manager 16 | 17 | ament_lint_auto 18 | ament_lint_common 19 | 20 | 21 | ament_cmake 22 | 23 | 24 | -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_cpp_examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(bumperbot_cpp_examples) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | find_package(ament_cmake REQUIRED) 9 | find_package(rclcpp REQUIRED) 10 | find_package(std_msgs REQUIRED) 11 | find_package(rcl_interfaces REQUIRED) 12 | 13 | add_executable(simple_publisher src/simple_publisher.cpp) 14 | ament_target_dependencies(simple_publisher rclcpp std_msgs) 15 | 16 | add_executable(simple_subscriber src/simple_subscriber.cpp) 17 | ament_target_dependencies(simple_subscriber rclcpp std_msgs) 18 | 19 | add_executable(simple_parameter src/simple_parameter.cpp) 20 | ament_target_dependencies(simple_parameter rclcpp rcl_interfaces) 21 | 22 | 23 | install(TARGETS 24 | simple_publisher 25 | simple_subscriber 26 | simple_parameter 27 | DESTINATION lib/${PROJECT_NAME} 28 | ) 29 | 30 | ament_package() -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_cpp_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_cpp_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | rclcpp 12 | std_msgs 13 | rcl_interfaces 14 | 15 | ament_lint_auto 16 | ament_lint_common 17 | 18 | 19 | ament_cmake 20 | 21 | -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_publisher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | 7 | using namespace std::chrono_literals; 8 | 9 | class SimplePublisher : public rclcpp::Node 10 | { 11 | public: 12 | SimplePublisher() : Node("simple_publisher"), counter_(0) 13 | { 14 | pub_ = create_publisher("chatter", 10); 15 | timer_ = create_wall_timer(1s, std::bind(&SimplePublisher::timerCallback, this)); 16 | RCLCPP_INFO(get_logger(), "Publishing at 1 Hz"); 17 | } 18 | 19 | void timerCallback() 20 | { 21 | auto message = std_msgs::msg::String(); 22 | message.data = "Hello ROS 2 - counter:" + std::to_string(counter_++); 23 | pub_->publish(message); 24 | } 25 | 26 | private: 27 | rclcpp::Publisher::SharedPtr pub_; 28 | rclcpp::TimerBase::SharedPtr timer_; 29 | unsigned int counter_; 30 | }; 31 | 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | rclcpp::init(argc, argv); 36 | auto node = std::make_shared(); 37 | rclcpp::spin(node); 38 | rclcpp::shutdown(); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_subscriber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using std::placeholders::_1; 6 | 7 | class SimpleSubscriber : public rclcpp::Node 8 | { 9 | public: 10 | SimpleSubscriber() : Node("simple_subscriber") 11 | { 12 | sub_ = create_subscription( 13 | "chatter", 10, std::bind(&SimpleSubscriber::msgCallback, this, _1)); 14 | } 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr sub_; 18 | 19 | void msgCallback(const std_msgs::msg::String &msg) const 20 | { 21 | RCLCPP_INFO_STREAM(this->get_logger(), "I heard: " << msg.data.c_str()); 22 | } 23 | }; 24 | 25 | 26 | int main(int argc, char * argv[]) 27 | { 28 | rclcpp::init(argc, argv); 29 | rclcpp::spin(std::make_shared()); 30 | rclcpp::shutdown(); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_description/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(bumperbot_description) 3 | 4 | 5 | find_package(ament_cmake REQUIRED) 6 | find_package(urdf REQUIRED) 7 | 8 | install( 9 | DIRECTORY launch meshes urdf rviz 10 | DESTINATION share/${PROJECT_NAME} 11 | ) 12 | 13 | if(BUILD_TESTING) 14 | find_package(ament_lint_auto REQUIRED) 15 | ament_lint_auto_find_test_dependencies() 16 | endif() 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section5_Control/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section5_Control/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section5_Control/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section5_Control/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section5_Control/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section5_Control/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_description/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_description 5 | 0.0.0 6 | Bumperbot Description package 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | 12 | robot_state_publisher 13 | urdf 14 | joint_state_publisher_gui 15 | rviz2 16 | xacro 17 | ros2launch 18 | ros_gz_sim 19 | gz_ros2_control 20 | ign_ros2_control 21 | 22 | ament_lint_auto 23 | ament_lint_common 24 | 25 | 26 | ament_cmake 27 | 28 | -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section5_Control/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_publisher.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimplePublisher(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_publisher") 10 | self.pub_ = self.create_publisher(String, "chatter", 10) 11 | self.counter_ = 0 12 | self.frequency_ = 1.0 13 | self.get_logger().info("Publishing at %d Hz" % self.frequency_) 14 | 15 | self.timer_ = self.create_timer(self.frequency_, self.timerCallback) 16 | 17 | def timerCallback(self): 18 | msg = String() 19 | msg.data = "Hello ROS 2 - counter: %d" % self.counter_ 20 | self.pub_.publish(msg) 21 | self.counter_ += 1 22 | 23 | 24 | def main(): 25 | rclpy.init() 26 | 27 | simple_publisher = SimplePublisher() 28 | rclpy.spin(simple_publisher) 29 | 30 | simple_publisher.destroy_node() 31 | rclpy.shutdown() 32 | 33 | 34 | if __name__ == '__main__': 35 | main() -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_subscriber.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimpleSubscriber(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_subscriber") 10 | self.sub_ = self.create_subscription(String, "chatter", self.msgCallback, 10) 11 | self.sub_ 12 | 13 | def msgCallback(self, msg): 14 | self.get_logger().info("I heard: %s" % msg.data) 15 | 16 | 17 | def main(): 18 | rclpy.init() 19 | 20 | simple_publisher = SimpleSubscriber() 21 | rclpy.spin(simple_publisher) 22 | 23 | simple_publisher.destroy_node() 24 | rclpy.shutdown() 25 | 26 | 27 | if __name__ == '__main__': 28 | main() -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_py_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_py_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | rclpy 11 | std_msgs 12 | rcl_interfaces 13 | 14 | ament_copyright 15 | ament_flake8 16 | ament_pep257 17 | python3-pytest 18 | 19 | 20 | ament_python 21 | 22 | 23 | -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section5_Control/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_py_examples/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/bumperbot_py_examples 3 | [install] 4 | install_scripts=$base/lib/bumperbot_py_examples 5 | -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_py_examples/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | package_name = 'bumperbot_py_examples' 4 | 5 | setup( 6 | name=package_name, 7 | version='0.0.0', 8 | packages=[package_name], 9 | data_files=[ 10 | ('share/ament_index/resource_index/packages', 11 | ['resource/' + package_name]), 12 | ('share/' + package_name, ['package.xml']), 13 | ], 14 | install_requires=['setuptools'], 15 | zip_safe=True, 16 | maintainer='user', 17 | maintainer_email='antonio.brandi@outlook.it', 18 | description='ROS 2 Code Examples', 19 | license='Apache 2.0', 20 | tests_require=['pytest'], 21 | entry_points={ 22 | 'console_scripts': [ 23 | 'simple_publisher = bumperbot_py_examples.simple_publisher:main', 24 | 'simple_subscriber = bumperbot_py_examples.simple_subscriber:main', 25 | 'simple_parameter = bumperbot_py_examples.simple_parameter:main', 26 | ], 27 | }, 28 | ) -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_py_examples/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_py_examples/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /Section5_Control/bumperbot_ws/src/bumperbot_py_examples/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_controller/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(bumperbot_controller) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | 6 | install( 7 | DIRECTORY launch config 8 | DESTINATION share/${PROJECT_NAME} 9 | ) 10 | 11 | ament_package() -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_controller/config/bumperbot_controllers.yaml: -------------------------------------------------------------------------------- 1 | controller_manager: 2 | ros__parameters: 3 | update_rate: 100 # Hz 4 | use_sim_time: true 5 | 6 | joint_state_broadcaster: 7 | type: joint_state_broadcaster/JointStateBroadcaster 8 | 9 | simple_velocity_controller: 10 | type: velocity_controllers/JointGroupVelocityController 11 | 12 | 13 | simple_velocity_controller: 14 | ros__parameters: 15 | joints: 16 | - wheel_left_joint 17 | - wheel_right_joint -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_controller/launch/controller.launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | from launch import LaunchDescription 3 | from launch_ros.actions import Node 4 | 5 | 6 | def generate_launch_description(): 7 | 8 | joint_state_broadcaster_spawner = Node( 9 | package="controller_manager", 10 | executable="spawner", 11 | arguments=[ 12 | "joint_state_broadcaster", 13 | "--controller-manager", 14 | "/controller_manager", 15 | ], 16 | ) 17 | 18 | simple_controller = Node( 19 | package="controller_manager", 20 | executable="spawner", 21 | arguments=["simple_velocity_controller", 22 | "--controller-manager", 23 | "/controller_manager" 24 | ] 25 | ) 26 | 27 | return LaunchDescription( 28 | [ 29 | joint_state_broadcaster_spawner, 30 | simple_controller, 31 | ] 32 | ) -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_controller/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | bumperbot_controller 4 | 0.0.0 5 | The bumperbot_controller package 6 | Antonio Brandi 7 | Apache 2.0 8 | Antonio Brandi 9 | 10 | ament_cmake 11 | 12 | ros2launch 13 | robot_state_publisher 14 | xacro 15 | controller_manager 16 | 17 | ament_lint_auto 18 | ament_lint_common 19 | 20 | 21 | ament_cmake 22 | 23 | 24 | -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_cpp_examples/include/bumperbot_cpp_examples/simple_turtlesim_kinematics.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_TURTLESIM_KINEMATICS_HPP 2 | #define SIMPLE_TURTLESIM_KINEMATICS_HPP 3 | 4 | #include 5 | #include 6 | 7 | class SimpleTurtlesimKinematics : public rclcpp::Node 8 | { 9 | public: 10 | SimpleTurtlesimKinematics(const std::string& name); 11 | 12 | void turtle1PoseCallback(const turtlesim::msg::Pose& pose); 13 | 14 | void turtle2PoseCallback(const turtlesim::msg::Pose& pose); 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr turtle1_pose_sub_; 18 | rclcpp::Subscription::SharedPtr turtle2_pose_sub_; 19 | 20 | turtlesim::msg::Pose last_turtle1_pose_; 21 | turtlesim::msg::Pose last_turtle2_pose_; 22 | }; 23 | 24 | #endif // SIMPLE_TURTLESIM_KINEMATICS_HPP -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_cpp_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_cpp_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | rclcpp 12 | std_msgs 13 | rcl_interfaces 14 | turtlesim 15 | 16 | ament_lint_auto 17 | ament_lint_common 18 | 19 | 20 | ament_cmake 21 | 22 | -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_publisher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | 7 | using namespace std::chrono_literals; 8 | 9 | class SimplePublisher : public rclcpp::Node 10 | { 11 | public: 12 | SimplePublisher() : Node("simple_publisher"), counter_(0) 13 | { 14 | pub_ = create_publisher("chatter", 10); 15 | timer_ = create_wall_timer(1s, std::bind(&SimplePublisher::timerCallback, this)); 16 | RCLCPP_INFO(get_logger(), "Publishing at 1 Hz"); 17 | } 18 | 19 | void timerCallback() 20 | { 21 | auto message = std_msgs::msg::String(); 22 | message.data = "Hello ROS 2 - counter:" + std::to_string(counter_++); 23 | pub_->publish(message); 24 | } 25 | 26 | private: 27 | rclcpp::Publisher::SharedPtr pub_; 28 | rclcpp::TimerBase::SharedPtr timer_; 29 | unsigned int counter_; 30 | }; 31 | 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | rclcpp::init(argc, argv); 36 | auto node = std::make_shared(); 37 | rclcpp::spin(node); 38 | rclcpp::shutdown(); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_subscriber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using std::placeholders::_1; 6 | 7 | class SimpleSubscriber : public rclcpp::Node 8 | { 9 | public: 10 | SimpleSubscriber() : Node("simple_subscriber") 11 | { 12 | sub_ = create_subscription( 13 | "chatter", 10, std::bind(&SimpleSubscriber::msgCallback, this, _1)); 14 | } 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr sub_; 18 | 19 | void msgCallback(const std_msgs::msg::String &msg) const 20 | { 21 | RCLCPP_INFO_STREAM(this->get_logger(), "I heard: " << msg.data.c_str()); 22 | } 23 | }; 24 | 25 | 26 | int main(int argc, char * argv[]) 27 | { 28 | rclcpp::init(argc, argv); 29 | rclcpp::spin(std::make_shared()); 30 | rclcpp::shutdown(); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_description/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(bumperbot_description) 3 | 4 | 5 | find_package(ament_cmake REQUIRED) 6 | find_package(urdf REQUIRED) 7 | 8 | install( 9 | DIRECTORY launch meshes urdf rviz 10 | DESTINATION share/${PROJECT_NAME} 11 | ) 12 | 13 | if(BUILD_TESTING) 14 | find_package(ament_lint_auto REQUIRED) 15 | ament_lint_auto_find_test_dependencies() 16 | endif() 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section6_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section6_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section6_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section6_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section6_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section6_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_description/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_description 5 | 0.0.0 6 | Bumperbot Description package 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | 12 | robot_state_publisher 13 | urdf 14 | joint_state_publisher_gui 15 | rviz2 16 | xacro 17 | ros2launch 18 | ros_gz_sim 19 | gz_ros2_control 20 | ign_ros2_control 21 | 22 | ament_lint_auto 23 | ament_lint_common 24 | 25 | 26 | ament_cmake 27 | 28 | -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section6_Kinematics/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_publisher.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimplePublisher(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_publisher") 10 | self.pub_ = self.create_publisher(String, "chatter", 10) 11 | self.counter_ = 0 12 | self.frequency_ = 1.0 13 | self.get_logger().info("Publishing at %d Hz" % self.frequency_) 14 | 15 | self.timer_ = self.create_timer(self.frequency_, self.timerCallback) 16 | 17 | def timerCallback(self): 18 | msg = String() 19 | msg.data = "Hello ROS 2 - counter: %d" % self.counter_ 20 | self.pub_.publish(msg) 21 | self.counter_ += 1 22 | 23 | 24 | def main(): 25 | rclpy.init() 26 | 27 | simple_publisher = SimplePublisher() 28 | rclpy.spin(simple_publisher) 29 | 30 | simple_publisher.destroy_node() 31 | rclpy.shutdown() 32 | 33 | 34 | if __name__ == '__main__': 35 | main() -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_subscriber.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimpleSubscriber(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_subscriber") 10 | self.sub_ = self.create_subscription(String, "chatter", self.msgCallback, 10) 11 | self.sub_ 12 | 13 | def msgCallback(self, msg): 14 | self.get_logger().info("I heard: %s" % msg.data) 15 | 16 | 17 | def main(): 18 | rclpy.init() 19 | 20 | simple_publisher = SimpleSubscriber() 21 | rclpy.spin(simple_publisher) 22 | 23 | simple_publisher.destroy_node() 24 | rclpy.shutdown() 25 | 26 | 27 | if __name__ == '__main__': 28 | main() -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_py_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_py_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | rclpy 11 | std_msgs 12 | rcl_interfaces 13 | turtlesim 14 | 15 | ament_copyright 16 | ament_flake8 17 | ament_pep257 18 | python3-pytest 19 | 20 | 21 | ament_python 22 | 23 | 24 | -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section6_Kinematics/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_py_examples/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/bumperbot_py_examples 3 | [install] 4 | install_scripts=$base/lib/bumperbot_py_examples 5 | -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_py_examples/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | package_name = 'bumperbot_py_examples' 4 | 5 | setup( 6 | name=package_name, 7 | version='0.0.0', 8 | packages=[package_name], 9 | data_files=[ 10 | ('share/ament_index/resource_index/packages', 11 | ['resource/' + package_name]), 12 | ('share/' + package_name, ['package.xml']), 13 | ], 14 | install_requires=['setuptools'], 15 | zip_safe=True, 16 | maintainer='user', 17 | maintainer_email='antonio.brandi@outlook.it', 18 | description='ROS 2 Code Examples', 19 | license='Apache 2.0', 20 | tests_require=['pytest'], 21 | entry_points={ 22 | 'console_scripts': [ 23 | 'simple_publisher = bumperbot_py_examples.simple_publisher:main', 24 | 'simple_subscriber = bumperbot_py_examples.simple_subscriber:main', 25 | 'simple_parameter = bumperbot_py_examples.simple_parameter:main', 26 | 'simple_turtlesim_kinematics = bumperbot_py_examples.simple_turtlesim_kinematics:main', 27 | ], 28 | }, 29 | ) -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_py_examples/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_py_examples/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /Section6_Kinematics/bumperbot_ws/src/bumperbot_py_examples/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_controller/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(bumperbot_controller) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | find_package(ament_cmake_python REQUIRED) 6 | find_package(rclcpp REQUIRED) 7 | find_package(rclpy REQUIRED) 8 | find_package(geometry_msgs REQUIRED) 9 | find_package(std_msgs REQUIRED) 10 | find_package(Eigen3 REQUIRED) 11 | 12 | include_directories(include) 13 | include_directories(${EIGEN3_INCLUDE_DIR}) 14 | 15 | add_executable(simple_controller src/simple_controller.cpp) 16 | ament_target_dependencies(simple_controller rclcpp geometry_msgs std_msgs ${Eigen_LIBRARIES}) 17 | 18 | ament_python_install_package(${PROJECT_NAME}) 19 | 20 | install( 21 | DIRECTORY include 22 | DESTINATION include 23 | ) 24 | 25 | install(TARGETS 26 | simple_controller 27 | DESTINATION lib/${PROJECT_NAME} 28 | ) 29 | 30 | install( 31 | DIRECTORY launch config 32 | DESTINATION share/${PROJECT_NAME} 33 | ) 34 | 35 | install(PROGRAMS 36 | ${PROJECT_NAME}/simple_controller.py 37 | DESTINATION lib/${PROJECT_NAME} 38 | ) 39 | 40 | ament_package() -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_controller/bumperbot_controller/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_controller/bumperbot_controller/__init__.py -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_controller/config/joy_config.yaml: -------------------------------------------------------------------------------- 1 | joystick: 2 | ros__parameters: 3 | device_id: 0 4 | device_name: "" 5 | deadzone: 0.5 6 | autorepeat_rate: 20.0 7 | sticky_buttons: false 8 | coalesce_interval_ms: 1 -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_controller/config/joy_teleop.yaml: -------------------------------------------------------------------------------- 1 | joy_teleop: 2 | ros__parameters: 3 | move: 4 | type: topic 5 | interface_type: geometry_msgs/msg/TwistStamped 6 | topic_name: bumperbot_controller/cmd_vel 7 | deadman_buttons: [5] 8 | axis_mappings: 9 | twist-linear-x: 10 | axis: 1 11 | scale: 1.0 12 | offset: 0.0 13 | twist-angular-z: 14 | axis: 3 15 | scale: 8.0 16 | offset: 0.0 -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_controller/include/bumperbot_controller/simple_controller.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_CONTROLLER_HPP 2 | #define SIMPLE_CONTROLLER_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | class SimpleController : public rclcpp::Node 11 | { 12 | public: 13 | SimpleController(const std::string& name); 14 | 15 | private: 16 | void velCallback(const geometry_msgs::msg::TwistStamped &msg); 17 | 18 | rclcpp::Subscription::SharedPtr vel_sub_; 19 | rclcpp::Publisher::SharedPtr wheel_cmd_pub_; 20 | 21 | double wheel_radius_; 22 | double wheel_separation_; 23 | Eigen::Matrix2d speed_conversion_; 24 | }; 25 | 26 | #endif // SIMPLE_CONTROLLER_HPP -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_controller/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | bumperbot_controller 4 | 0.0.0 5 | The bumperbot_controller package 6 | Antonio Brandi 7 | Apache 2.0 8 | Antonio Brandi 9 | 10 | ament_cmake 11 | ament_cmake_python 12 | 13 | rclcpp 14 | rclpy 15 | geometry_msgs 16 | std_msgs 17 | eigen 18 | 19 | ros2launch 20 | robot_state_publisher 21 | xacro 22 | controller_manager 23 | joy 24 | joy_teleop 25 | ros2_controllers 26 | 27 | ament_lint_auto 28 | ament_lint_common 29 | 30 | 31 | ament_cmake 32 | 33 | 34 | -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_cpp_examples/include/bumperbot_cpp_examples/simple_turtlesim_kinematics.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_TURTLESIM_KINEMATICS_HPP 2 | #define SIMPLE_TURTLESIM_KINEMATICS_HPP 3 | 4 | #include 5 | #include 6 | 7 | class SimpleTurtlesimKinematics : public rclcpp::Node 8 | { 9 | public: 10 | SimpleTurtlesimKinematics(const std::string& name); 11 | 12 | void turtle1PoseCallback(const turtlesim::msg::Pose& pose); 13 | 14 | void turtle2PoseCallback(const turtlesim::msg::Pose& pose); 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr turtle1_pose_sub_; 18 | rclcpp::Subscription::SharedPtr turtle2_pose_sub_; 19 | 20 | turtlesim::msg::Pose last_turtle1_pose_; 21 | turtlesim::msg::Pose last_turtle2_pose_; 22 | }; 23 | 24 | #endif // SIMPLE_TURTLESIM_KINEMATICS_HPP -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_cpp_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_cpp_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | rclcpp 12 | std_msgs 13 | rcl_interfaces 14 | turtlesim 15 | 16 | ament_lint_auto 17 | ament_lint_common 18 | 19 | 20 | ament_cmake 21 | 22 | -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_publisher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | 7 | using namespace std::chrono_literals; 8 | 9 | class SimplePublisher : public rclcpp::Node 10 | { 11 | public: 12 | SimplePublisher() : Node("simple_publisher"), counter_(0) 13 | { 14 | pub_ = create_publisher("chatter", 10); 15 | timer_ = create_wall_timer(1s, std::bind(&SimplePublisher::timerCallback, this)); 16 | RCLCPP_INFO(get_logger(), "Publishing at 1 Hz"); 17 | } 18 | 19 | void timerCallback() 20 | { 21 | auto message = std_msgs::msg::String(); 22 | message.data = "Hello ROS 2 - counter:" + std::to_string(counter_++); 23 | pub_->publish(message); 24 | } 25 | 26 | private: 27 | rclcpp::Publisher::SharedPtr pub_; 28 | rclcpp::TimerBase::SharedPtr timer_; 29 | unsigned int counter_; 30 | }; 31 | 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | rclcpp::init(argc, argv); 36 | auto node = std::make_shared(); 37 | rclcpp::spin(node); 38 | rclcpp::shutdown(); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_subscriber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using std::placeholders::_1; 6 | 7 | class SimpleSubscriber : public rclcpp::Node 8 | { 9 | public: 10 | SimpleSubscriber() : Node("simple_subscriber") 11 | { 12 | sub_ = create_subscription( 13 | "chatter", 10, std::bind(&SimpleSubscriber::msgCallback, this, _1)); 14 | } 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr sub_; 18 | 19 | void msgCallback(const std_msgs::msg::String &msg) const 20 | { 21 | RCLCPP_INFO_STREAM(this->get_logger(), "I heard: " << msg.data.c_str()); 22 | } 23 | }; 24 | 25 | 26 | int main(int argc, char * argv[]) 27 | { 28 | rclcpp::init(argc, argv); 29 | rclcpp::spin(std::make_shared()); 30 | rclcpp::shutdown(); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(bumperbot_description) 3 | 4 | 5 | find_package(ament_cmake REQUIRED) 6 | find_package(urdf REQUIRED) 7 | 8 | install( 9 | DIRECTORY launch meshes urdf rviz 10 | DESTINATION share/${PROJECT_NAME} 11 | ) 12 | 13 | if(BUILD_TESTING) 14 | find_package(ament_lint_auto REQUIRED) 15 | ament_lint_auto_find_test_dependencies() 16 | endif() 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_description/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_description 5 | 0.0.0 6 | Bumperbot Description package 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | 12 | robot_state_publisher 13 | urdf 14 | joint_state_publisher_gui 15 | rviz2 16 | xacro 17 | ros2launch 18 | ros_gz_sim 19 | gz_ros2_control 20 | ign_ros2_control 21 | 22 | ament_lint_auto 23 | ament_lint_common 24 | 25 | 26 | ament_cmake 27 | 28 | -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_publisher.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimplePublisher(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_publisher") 10 | self.pub_ = self.create_publisher(String, "chatter", 10) 11 | self.counter_ = 0 12 | self.frequency_ = 1.0 13 | self.get_logger().info("Publishing at %d Hz" % self.frequency_) 14 | 15 | self.timer_ = self.create_timer(self.frequency_, self.timerCallback) 16 | 17 | def timerCallback(self): 18 | msg = String() 19 | msg.data = "Hello ROS 2 - counter: %d" % self.counter_ 20 | self.pub_.publish(msg) 21 | self.counter_ += 1 22 | 23 | 24 | def main(): 25 | rclpy.init() 26 | 27 | simple_publisher = SimplePublisher() 28 | rclpy.spin(simple_publisher) 29 | 30 | simple_publisher.destroy_node() 31 | rclpy.shutdown() 32 | 33 | 34 | if __name__ == '__main__': 35 | main() -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_subscriber.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimpleSubscriber(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_subscriber") 10 | self.sub_ = self.create_subscription(String, "chatter", self.msgCallback, 10) 11 | self.sub_ 12 | 13 | def msgCallback(self, msg): 14 | self.get_logger().info("I heard: %s" % msg.data) 15 | 16 | 17 | def main(): 18 | rclpy.init() 19 | 20 | simple_publisher = SimpleSubscriber() 21 | rclpy.spin(simple_publisher) 22 | 23 | simple_publisher.destroy_node() 24 | rclpy.shutdown() 25 | 26 | 27 | if __name__ == '__main__': 28 | main() -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_py_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_py_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | rclpy 11 | std_msgs 12 | rcl_interfaces 13 | turtlesim 14 | 15 | ament_copyright 16 | ament_flake8 17 | ament_pep257 18 | python3-pytest 19 | 20 | 21 | ament_python 22 | 23 | 24 | -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_py_examples/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/bumperbot_py_examples 3 | [install] 4 | install_scripts=$base/lib/bumperbot_py_examples 5 | -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_py_examples/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | package_name = 'bumperbot_py_examples' 4 | 5 | setup( 6 | name=package_name, 7 | version='0.0.0', 8 | packages=[package_name], 9 | data_files=[ 10 | ('share/ament_index/resource_index/packages', 11 | ['resource/' + package_name]), 12 | ('share/' + package_name, ['package.xml']), 13 | ], 14 | install_requires=['setuptools'], 15 | zip_safe=True, 16 | maintainer='user', 17 | maintainer_email='antonio.brandi@outlook.it', 18 | description='ROS 2 Code Examples', 19 | license='Apache 2.0', 20 | tests_require=['pytest'], 21 | entry_points={ 22 | 'console_scripts': [ 23 | 'simple_publisher = bumperbot_py_examples.simple_publisher:main', 24 | 'simple_subscriber = bumperbot_py_examples.simple_subscriber:main', 25 | 'simple_parameter = bumperbot_py_examples.simple_parameter:main', 26 | 'simple_turtlesim_kinematics = bumperbot_py_examples.simple_turtlesim_kinematics:main', 27 | ], 28 | }, 29 | ) -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_py_examples/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_py_examples/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /Section7_Differential_Kinematics/bumperbot_ws/src/bumperbot_py_examples/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_controller/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(bumperbot_controller) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | find_package(ament_cmake_python REQUIRED) 6 | find_package(rclcpp REQUIRED) 7 | find_package(rclpy REQUIRED) 8 | find_package(geometry_msgs REQUIRED) 9 | find_package(std_msgs REQUIRED) 10 | find_package(Eigen3 REQUIRED) 11 | 12 | include_directories(include) 13 | include_directories(${EIGEN3_INCLUDE_DIR}) 14 | 15 | add_executable(simple_controller src/simple_controller.cpp) 16 | ament_target_dependencies(simple_controller rclcpp geometry_msgs std_msgs ${Eigen_LIBRARIES}) 17 | 18 | ament_python_install_package(${PROJECT_NAME}) 19 | 20 | install( 21 | DIRECTORY include 22 | DESTINATION include 23 | ) 24 | 25 | install(TARGETS 26 | simple_controller 27 | DESTINATION lib/${PROJECT_NAME} 28 | ) 29 | 30 | install( 31 | DIRECTORY launch config 32 | DESTINATION share/${PROJECT_NAME} 33 | ) 34 | 35 | install(PROGRAMS 36 | ${PROJECT_NAME}/simple_controller.py 37 | DESTINATION lib/${PROJECT_NAME} 38 | ) 39 | 40 | ament_package() -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_controller/bumperbot_controller/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section8_TF2_Library/bumperbot_ws/src/bumperbot_controller/bumperbot_controller/__init__.py -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_controller/config/joy_config.yaml: -------------------------------------------------------------------------------- 1 | joystick: 2 | ros__parameters: 3 | device_id: 0 4 | device_name: "" 5 | deadzone: 0.5 6 | autorepeat_rate: 20.0 7 | sticky_buttons: false 8 | coalesce_interval_ms: 1 -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_controller/config/joy_teleop.yaml: -------------------------------------------------------------------------------- 1 | joy_teleop: 2 | ros__parameters: 3 | move: 4 | type: topic 5 | interface_type: geometry_msgs/msg/TwistStamped 6 | topic_name: bumperbot_controller/cmd_vel 7 | deadman_buttons: [5] 8 | axis_mappings: 9 | twist-linear-x: 10 | axis: 1 11 | scale: 1.0 12 | offset: 0.0 13 | twist-angular-z: 14 | axis: 3 15 | scale: 8.0 16 | offset: 0.0 -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_controller/include/bumperbot_controller/simple_controller.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_CONTROLLER_HPP 2 | #define SIMPLE_CONTROLLER_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | class SimpleController : public rclcpp::Node 11 | { 12 | public: 13 | SimpleController(const std::string& name); 14 | 15 | private: 16 | void velCallback(const geometry_msgs::msg::TwistStamped &msg); 17 | 18 | rclcpp::Subscription::SharedPtr vel_sub_; 19 | rclcpp::Publisher::SharedPtr wheel_cmd_pub_; 20 | 21 | double wheel_radius_; 22 | double wheel_separation_; 23 | Eigen::Matrix2d speed_conversion_; 24 | }; 25 | 26 | #endif // SIMPLE_CONTROLLER_HPP -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_controller/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | bumperbot_controller 4 | 0.0.0 5 | The bumperbot_controller package 6 | Antonio Brandi 7 | Apache 2.0 8 | Antonio Brandi 9 | 10 | ament_cmake 11 | ament_cmake_python 12 | 13 | rclcpp 14 | rclpy 15 | geometry_msgs 16 | std_msgs 17 | eigen 18 | 19 | ros2launch 20 | robot_state_publisher 21 | xacro 22 | controller_manager 23 | joy 24 | joy_teleop 25 | ros2_controllers 26 | 27 | ament_lint_auto 28 | ament_lint_common 29 | 30 | 31 | ament_cmake 32 | 33 | 34 | -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_cpp_examples/include/bumperbot_cpp_examples/simple_turtlesim_kinematics.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_TURTLESIM_KINEMATICS_HPP 2 | #define SIMPLE_TURTLESIM_KINEMATICS_HPP 3 | 4 | #include 5 | #include 6 | 7 | class SimpleTurtlesimKinematics : public rclcpp::Node 8 | { 9 | public: 10 | SimpleTurtlesimKinematics(const std::string& name); 11 | 12 | void turtle1PoseCallback(const turtlesim::msg::Pose& pose); 13 | 14 | void turtle2PoseCallback(const turtlesim::msg::Pose& pose); 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr turtle1_pose_sub_; 18 | rclcpp::Subscription::SharedPtr turtle2_pose_sub_; 19 | 20 | turtlesim::msg::Pose last_turtle1_pose_; 21 | turtlesim::msg::Pose last_turtle2_pose_; 22 | }; 23 | 24 | #endif // SIMPLE_TURTLESIM_KINEMATICS_HPP -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_cpp_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_cpp_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | rclcpp 12 | std_msgs 13 | rcl_interfaces 14 | turtlesim 15 | bumperbot_msgs 16 | geometry_msgs 17 | tf2 18 | tf2_ros 19 | 20 | ament_lint_auto 21 | ament_lint_common 22 | 23 | 24 | ament_cmake 25 | 26 | -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_publisher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | 7 | using namespace std::chrono_literals; 8 | 9 | class SimplePublisher : public rclcpp::Node 10 | { 11 | public: 12 | SimplePublisher() : Node("simple_publisher"), counter_(0) 13 | { 14 | pub_ = create_publisher("chatter", 10); 15 | timer_ = create_wall_timer(1s, std::bind(&SimplePublisher::timerCallback, this)); 16 | RCLCPP_INFO(get_logger(), "Publishing at 1 Hz"); 17 | } 18 | 19 | void timerCallback() 20 | { 21 | auto message = std_msgs::msg::String(); 22 | message.data = "Hello ROS 2 - counter:" + std::to_string(counter_++); 23 | pub_->publish(message); 24 | } 25 | 26 | private: 27 | rclcpp::Publisher::SharedPtr pub_; 28 | rclcpp::TimerBase::SharedPtr timer_; 29 | unsigned int counter_; 30 | }; 31 | 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | rclcpp::init(argc, argv); 36 | auto node = std::make_shared(); 37 | rclcpp::spin(node); 38 | rclcpp::shutdown(); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_subscriber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using std::placeholders::_1; 6 | 7 | class SimpleSubscriber : public rclcpp::Node 8 | { 9 | public: 10 | SimpleSubscriber() : Node("simple_subscriber") 11 | { 12 | sub_ = create_subscription( 13 | "chatter", 10, std::bind(&SimpleSubscriber::msgCallback, this, _1)); 14 | } 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr sub_; 18 | 19 | void msgCallback(const std_msgs::msg::String &msg) const 20 | { 21 | RCLCPP_INFO_STREAM(this->get_logger(), "I heard: " << msg.data.c_str()); 22 | } 23 | }; 24 | 25 | 26 | int main(int argc, char * argv[]) 27 | { 28 | rclcpp::init(argc, argv); 29 | rclcpp::spin(std::make_shared()); 30 | rclcpp::shutdown(); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(bumperbot_description) 3 | 4 | 5 | find_package(ament_cmake REQUIRED) 6 | find_package(urdf REQUIRED) 7 | 8 | install( 9 | DIRECTORY launch meshes urdf rviz 10 | DESTINATION share/${PROJECT_NAME} 11 | ) 12 | 13 | if(BUILD_TESTING) 14 | find_package(ament_lint_auto REQUIRED) 15 | ament_lint_auto_find_test_dependencies() 16 | endif() 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_description/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_description 5 | 0.0.0 6 | Bumperbot Description package 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | 12 | robot_state_publisher 13 | urdf 14 | joint_state_publisher_gui 15 | rviz2 16 | xacro 17 | ros2launch 18 | ros_gz_sim 19 | gz_ros2_control 20 | ign_ros2_control 21 | 22 | ament_lint_auto 23 | ament_lint_common 24 | 25 | 26 | ament_cmake 27 | 28 | -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_msgs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(bumperbot_msgs) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | find_package(ament_cmake REQUIRED) 9 | find_package(geometry_msgs REQUIRED) 10 | find_package(rosidl_default_generators REQUIRED) 11 | 12 | rosidl_generate_interfaces(${PROJECT_NAME} 13 | "srv/AddTwoInts.srv" 14 | "srv/GetTransform.srv" 15 | DEPENDENCIES geometry_msgs 16 | ) 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_msgs/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_msgs 5 | 0.0.0 6 | Definition of Interfaces for the bumperbot 7 | Antonio Brandi 8 | Apàche 2.0 9 | 10 | ament_cmake 11 | rosidl_default_generators 12 | 13 | geometry_msgs 14 | 15 | rosidl_default_runtime 16 | 17 | rosidl_interface_packages 18 | 19 | ament_lint_auto 20 | ament_lint_common 21 | 22 | 23 | ament_cmake 24 | 25 | -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_msgs/srv/AddTwoInts.srv: -------------------------------------------------------------------------------- 1 | # Request 2 | int64 a 3 | int64 b 4 | --- 5 | # Response 6 | int64 sum -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_msgs/srv/GetTransform.srv: -------------------------------------------------------------------------------- 1 | # Request 2 | string frame_id 3 | string child_frame_id 4 | --- 5 | # Response 6 | geometry_msgs/TransformStamped transform 7 | bool success -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section8_TF2_Library/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_publisher.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimplePublisher(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_publisher") 10 | self.pub_ = self.create_publisher(String, "chatter", 10) 11 | self.counter_ = 0 12 | self.frequency_ = 1.0 13 | self.get_logger().info("Publishing at %d Hz" % self.frequency_) 14 | 15 | self.timer_ = self.create_timer(self.frequency_, self.timerCallback) 16 | 17 | def timerCallback(self): 18 | msg = String() 19 | msg.data = "Hello ROS 2 - counter: %d" % self.counter_ 20 | self.pub_.publish(msg) 21 | self.counter_ += 1 22 | 23 | 24 | def main(): 25 | rclpy.init() 26 | 27 | simple_publisher = SimplePublisher() 28 | rclpy.spin(simple_publisher) 29 | 30 | simple_publisher.destroy_node() 31 | rclpy.shutdown() 32 | 33 | 34 | if __name__ == '__main__': 35 | main() -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_service_server.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from bumperbot_msgs.srv import AddTwoInts 4 | 5 | 6 | class SimpleServiceServer(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_service_server") 10 | self.service_ = self.create_service(AddTwoInts, "add_two_ints", self.serviceCallback) 11 | self.get_logger().info("Service add_two_ints Ready") 12 | 13 | 14 | def serviceCallback(self, req, res): 15 | self.get_logger().info("New Request Received a: %d, b: %d" % (req.a, req.b)) 16 | res.sum = req.a + req.b 17 | self.get_logger().info("Returning sum: %d" % res.sum) 18 | return res 19 | 20 | 21 | def main(): 22 | rclpy.init() 23 | 24 | simple_service_server = SimpleServiceServer() 25 | rclpy.spin(simple_service_server) 26 | 27 | simple_service_server.destroy_node() 28 | rclpy.shutdown() 29 | 30 | 31 | if __name__ == '__main__': 32 | main() -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_subscriber.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimpleSubscriber(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_subscriber") 10 | self.sub_ = self.create_subscription(String, "chatter", self.msgCallback, 10) 11 | self.sub_ 12 | 13 | def msgCallback(self, msg): 14 | self.get_logger().info("I heard: %s" % msg.data) 15 | 16 | 17 | def main(): 18 | rclpy.init() 19 | 20 | simple_publisher = SimpleSubscriber() 21 | rclpy.spin(simple_publisher) 22 | 23 | simple_publisher.destroy_node() 24 | rclpy.shutdown() 25 | 26 | 27 | if __name__ == '__main__': 28 | main() -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_py_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_py_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | rclpy 11 | std_msgs 12 | rcl_interfaces 13 | turtlesim 14 | bumperbot_msgs 15 | tf2_ros 16 | geometry_msgs 17 | tf_transformations 18 | 19 | ament_copyright 20 | ament_flake8 21 | ament_pep257 22 | python3-pytest 23 | 24 | 25 | ament_python 26 | 27 | 28 | -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section8_TF2_Library/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_py_examples/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/bumperbot_py_examples 3 | [install] 4 | install_scripts=$base/lib/bumperbot_py_examples 5 | -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_py_examples/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_py_examples/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /Section8_TF2_Library/bumperbot_ws/src/bumperbot_py_examples/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_controller/bumperbot_controller/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section9_Odometry/bumperbot_ws/src/bumperbot_controller/bumperbot_controller/__init__.py -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_controller/config/joy_config.yaml: -------------------------------------------------------------------------------- 1 | joystick: 2 | ros__parameters: 3 | device_id: 0 4 | device_name: "" 5 | deadzone: 0.5 6 | autorepeat_rate: 20.0 7 | sticky_buttons: false 8 | coalesce_interval_ms: 1 -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_controller/config/joy_teleop.yaml: -------------------------------------------------------------------------------- 1 | joy_teleop: 2 | ros__parameters: 3 | move: 4 | type: topic 5 | interface_type: geometry_msgs/msg/TwistStamped 6 | topic_name: bumperbot_controller/cmd_vel 7 | deadman_buttons: [5] 8 | axis_mappings: 9 | twist-linear-x: 10 | axis: 1 11 | scale: 1.0 12 | offset: 0.0 13 | twist-angular-z: 14 | axis: 3 15 | scale: 8.0 16 | offset: 0.0 -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_cpp_examples/include/bumperbot_cpp_examples/simple_turtlesim_kinematics.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_TURTLESIM_KINEMATICS_HPP 2 | #define SIMPLE_TURTLESIM_KINEMATICS_HPP 3 | 4 | #include 5 | #include 6 | 7 | class SimpleTurtlesimKinematics : public rclcpp::Node 8 | { 9 | public: 10 | SimpleTurtlesimKinematics(const std::string& name); 11 | 12 | void turtle1PoseCallback(const turtlesim::msg::Pose& pose); 13 | 14 | void turtle2PoseCallback(const turtlesim::msg::Pose& pose); 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr turtle1_pose_sub_; 18 | rclcpp::Subscription::SharedPtr turtle2_pose_sub_; 19 | 20 | turtlesim::msg::Pose last_turtle1_pose_; 21 | turtlesim::msg::Pose last_turtle2_pose_; 22 | }; 23 | 24 | #endif // SIMPLE_TURTLESIM_KINEMATICS_HPP -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_cpp_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_cpp_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | rclcpp 12 | std_msgs 13 | rcl_interfaces 14 | turtlesim 15 | bumperbot_msgs 16 | geometry_msgs 17 | tf2 18 | tf2_ros 19 | 20 | ament_lint_auto 21 | ament_lint_common 22 | 23 | 24 | ament_cmake 25 | 26 | -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_publisher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | 7 | using namespace std::chrono_literals; 8 | 9 | class SimplePublisher : public rclcpp::Node 10 | { 11 | public: 12 | SimplePublisher() : Node("simple_publisher"), counter_(0) 13 | { 14 | pub_ = create_publisher("chatter", 10); 15 | timer_ = create_wall_timer(1s, std::bind(&SimplePublisher::timerCallback, this)); 16 | RCLCPP_INFO(get_logger(), "Publishing at 1 Hz"); 17 | } 18 | 19 | void timerCallback() 20 | { 21 | auto message = std_msgs::msg::String(); 22 | message.data = "Hello ROS 2 - counter:" + std::to_string(counter_++); 23 | pub_->publish(message); 24 | } 25 | 26 | private: 27 | rclcpp::Publisher::SharedPtr pub_; 28 | rclcpp::TimerBase::SharedPtr timer_; 29 | unsigned int counter_; 30 | }; 31 | 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | rclcpp::init(argc, argv); 36 | auto node = std::make_shared(); 37 | rclcpp::spin(node); 38 | rclcpp::shutdown(); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_cpp_examples/src/simple_subscriber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using std::placeholders::_1; 6 | 7 | class SimpleSubscriber : public rclcpp::Node 8 | { 9 | public: 10 | SimpleSubscriber() : Node("simple_subscriber") 11 | { 12 | sub_ = create_subscription( 13 | "chatter", 10, std::bind(&SimpleSubscriber::msgCallback, this, _1)); 14 | } 15 | 16 | private: 17 | rclcpp::Subscription::SharedPtr sub_; 18 | 19 | void msgCallback(const std_msgs::msg::String &msg) const 20 | { 21 | RCLCPP_INFO_STREAM(this->get_logger(), "I heard: " << msg.data.c_str()); 22 | } 23 | }; 24 | 25 | 26 | int main(int argc, char * argv[]) 27 | { 28 | rclcpp::init(argc, argv); 29 | rclcpp::spin(std::make_shared()); 30 | rclcpp::shutdown(); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_description/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(bumperbot_description) 3 | 4 | 5 | find_package(ament_cmake REQUIRED) 6 | find_package(urdf REQUIRED) 7 | 8 | install( 9 | DIRECTORY launch meshes urdf rviz 10 | DESTINATION share/${PROJECT_NAME} 11 | ) 12 | 13 | if(BUILD_TESTING) 14 | find_package(ament_lint_auto REQUIRED) 15 | ament_lint_auto_find_test_dependencies() 16 | endif() 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section9_Odometry/bumperbot_ws/src/bumperbot_description/meshes/base_link.STL -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section9_Odometry/bumperbot_ws/src/bumperbot_description/meshes/caster_front_link.STL -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section9_Odometry/bumperbot_ws/src/bumperbot_description/meshes/caster_rear_link.STL -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section9_Odometry/bumperbot_ws/src/bumperbot_description/meshes/imu_link.STL -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section9_Odometry/bumperbot_ws/src/bumperbot_description/meshes/wheel_left_link.STL -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section9_Odometry/bumperbot_ws/src/bumperbot_description/meshes/wheel_right_link.STL -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_description/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_description 5 | 0.0.0 6 | Bumperbot Description package 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | ament_cmake 11 | 12 | robot_state_publisher 13 | urdf 14 | joint_state_publisher_gui 15 | rviz2 16 | xacro 17 | ros2launch 18 | ros_gz_sim 19 | gz_ros2_control 20 | ign_ros2_control 21 | 22 | ament_lint_auto 23 | ament_lint_common 24 | 25 | 26 | ament_cmake 27 | 28 | -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_msgs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(bumperbot_msgs) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | find_package(ament_cmake REQUIRED) 9 | find_package(geometry_msgs REQUIRED) 10 | find_package(rosidl_default_generators REQUIRED) 11 | 12 | rosidl_generate_interfaces(${PROJECT_NAME} 13 | "srv/AddTwoInts.srv" 14 | "srv/GetTransform.srv" 15 | DEPENDENCIES geometry_msgs 16 | ) 17 | 18 | ament_package() -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_msgs/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_msgs 5 | 0.0.0 6 | Definition of Interfaces for the bumperbot 7 | Antonio Brandi 8 | Apàche 2.0 9 | 10 | ament_cmake 11 | rosidl_default_generators 12 | 13 | geometry_msgs 14 | 15 | rosidl_default_runtime 16 | 17 | rosidl_interface_packages 18 | 19 | ament_lint_auto 20 | ament_lint_common 21 | 22 | 23 | ament_cmake 24 | 25 | -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_msgs/srv/AddTwoInts.srv: -------------------------------------------------------------------------------- 1 | # Request 2 | int64 a 3 | int64 b 4 | --- 5 | # Response 6 | int64 sum -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_msgs/srv/GetTransform.srv: -------------------------------------------------------------------------------- 1 | # Request 2 | string frame_id 3 | string child_frame_id 4 | --- 5 | # Response 6 | geometry_msgs/TransformStamped transform 7 | bool success -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section9_Odometry/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/__init__.py -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_publisher.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimplePublisher(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_publisher") 10 | self.pub_ = self.create_publisher(String, "chatter", 10) 11 | self.counter_ = 0 12 | self.frequency_ = 1.0 13 | self.get_logger().info("Publishing at %d Hz" % self.frequency_) 14 | 15 | self.timer_ = self.create_timer(self.frequency_, self.timerCallback) 16 | 17 | def timerCallback(self): 18 | msg = String() 19 | msg.data = "Hello ROS 2 - counter: %d" % self.counter_ 20 | self.pub_.publish(msg) 21 | self.counter_ += 1 22 | 23 | 24 | def main(): 25 | rclpy.init() 26 | 27 | simple_publisher = SimplePublisher() 28 | rclpy.spin(simple_publisher) 29 | 30 | simple_publisher.destroy_node() 31 | rclpy.shutdown() 32 | 33 | 34 | if __name__ == '__main__': 35 | main() -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_service_server.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from bumperbot_msgs.srv import AddTwoInts 4 | 5 | 6 | class SimpleServiceServer(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_service_server") 10 | self.service_ = self.create_service(AddTwoInts, "add_two_ints", self.serviceCallback) 11 | self.get_logger().info("Service add_two_ints Ready") 12 | 13 | 14 | def serviceCallback(self, req, res): 15 | self.get_logger().info("New Request Received a: %d, b: %d" % (req.a, req.b)) 16 | res.sum = req.a + req.b 17 | self.get_logger().info("Returning sum: %d" % res.sum) 18 | return res 19 | 20 | 21 | def main(): 22 | rclpy.init() 23 | 24 | simple_service_server = SimpleServiceServer() 25 | rclpy.spin(simple_service_server) 26 | 27 | simple_service_server.destroy_node() 28 | rclpy.shutdown() 29 | 30 | 31 | if __name__ == '__main__': 32 | main() -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_py_examples/bumperbot_py_examples/simple_subscriber.py: -------------------------------------------------------------------------------- 1 | import rclpy 2 | from rclpy.node import Node 3 | from std_msgs.msg import String 4 | 5 | 6 | class SimpleSubscriber(Node): 7 | 8 | def __init__(self): 9 | super().__init__("simple_subscriber") 10 | self.sub_ = self.create_subscription(String, "chatter", self.msgCallback, 10) 11 | self.sub_ 12 | 13 | def msgCallback(self, msg): 14 | self.get_logger().info("I heard: %s" % msg.data) 15 | 16 | 17 | def main(): 18 | rclpy.init() 19 | 20 | simple_publisher = SimpleSubscriber() 21 | rclpy.spin(simple_publisher) 22 | 23 | simple_publisher.destroy_node() 24 | rclpy.shutdown() 25 | 26 | 27 | if __name__ == '__main__': 28 | main() -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_py_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bumperbot_py_examples 5 | 0.0.0 6 | ROS 2 Code Examples 7 | Antonio Brandi 8 | Apache 2.0 9 | 10 | rclpy 11 | std_msgs 12 | rcl_interfaces 13 | turtlesim 14 | bumperbot_msgs 15 | tf2_ros 16 | geometry_msgs 17 | tf_transformations 18 | 19 | ament_copyright 20 | ament_flake8 21 | ament_pep257 22 | python3-pytest 23 | 24 | 25 | ament_python 26 | 27 | 28 | -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/Section9_Odometry/bumperbot_ws/src/bumperbot_py_examples/resource/bumperbot_py_examples -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_py_examples/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/bumperbot_py_examples 3 | [install] 4 | install_scripts=$base/lib/bumperbot_py_examples 5 | -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_py_examples/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_py_examples/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /Section9_Odometry/bumperbot_ws/src/bumperbot_py_examples/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /images/cover_manipulators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/images/cover_manipulators.png -------------------------------------------------------------------------------- /images/cover_map_localization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/images/cover_map_localization.png -------------------------------------------------------------------------------- /images/cover_odometry_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/images/cover_odometry_control.png -------------------------------------------------------------------------------- /images/cover_plan_navigation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntoBrandi/Self-Driving-and-ROS-2-Learn-by-Doing-Odometry-Control/35d59db59b53cd2fa61e09de8215f43cf5c9e30c/images/cover_plan_navigation.png --------------------------------------------------------------------------------