Skip to the content.

image— layout: default —

Roboracer 2nd day

Ubuntu Installation with Virtualbox is done so it is time to install Docker in Ubuntu.

Open Terminal in Ubuntu

  1. update system : sudo apt update
  2. install docker: sudo apt install docker.io -y
  3. append user: sudo usermod -aG docker $USER
  4. reboot(for user rights): sudo reboot
  5. check docker: docker –version

[moving on to lab 1] Now we have VirtualBox VM (Ubuntu) and Docker, we will use 2.2 (Docker) for lab1

  1. Make working directory: mkdir -p ~/lab1_ws/src
  2. Download ROS2 Foxy image and run docker container: docker run -it -v ~/lab1_ws/src:/lab1_ws/src –name f1tenth_lab1 ros:foxy
  3. install tmux for multiple terminal inside Docker Container: apt update && apt install tmux

[How to use tmux] type tmux in terminal to start tmux session. Ctrl+b, then press next keys: c: new terminal n: next terminal d: detach terminal

[ROS2 basics working fine] source /opt/ros/foxy/setup.bash ros2 topic list

/parameter_events /rosout

Create workspace before creating a package cd /lab1_ws colcon build source install/setup.bash

[Creating a package] Deliverable 1:

cd /lab1_ws/src ros2 pkg create lab1_pkg –build-type ament_cmake –dependencies rclcpp rclpy ackermann_msgs

[If declared properly the depencies could be installed using rosdep] cd /lab1_ws rosdep install -i –from-path src –rosdistro foxy -y

[Creating nodes with publishers and subscribers] cd /lab1_ws/src/lab1_pkg mkdir -p scripts nano scripts/talker.py

editor pops up, code: #!/usr/bin/env python3 import rclpy from rclpy.node import Node from ackermann_msgs.msg import AckermannDriveStamped

class Talker(Node): def init(self): super().init(‘talker’) self.declare_parameter(‘v’, 0.0) self.declare_parameter(‘d’, 0.0) self.publisher = self.create_publisher(AckermannDriveStamped, ‘drive’, 10) self.timer = self.create_timer(0.1, self.timer_callback)

def timer_callback(self):
    msg = AckermannDriveStamped()
    msg.drive.speed = self.get_parameter('v').value
    msg.drive.steering_angle = self.get_parameter('d').value
    self.publisher.publish(msg)

def main(args=None): rclpy.init(args=args) node = Talker() rclpy.spin(node) node.destroy_node() rclpy.shutdown()

if name == ‘main’: main()

ctrl x, y, enter for save for rights: chmod +x scripts/talker.py

explanation: required Deliverable 2: talker node creation AckermannDriveStamped message publishing in drive topic v parameter → speed field d parameter → steering_angle field

code: Node class inheritence - ROS2 node creation declare_parameter - v, d parameter declaration create_publisher - publisher creation in drive topic timer_callback - message per 0.1 second

for clipboard sharing with virtual machine, we are going to install guest additions first get out of Docker with exit command

then sudo apt update sudo apt install virtualbox-guest-utils virtualbox-guest-x11 -y sudo reboot

then we will set Devices → Shared Clipboard → Bidirectional

This didn’t work because the screen of Ubuntu was cracking we had to deleted all guestAddition sudo /opt/VBoxGuestAdditions-*/uninstall.sh sudo reboot

and eject the guest additions cd image

[Start the Docker container again (after reboot)] docker start -i f1tenth_lab1

back here [Creating nodes with publishers and subscribers] cd /lab1_ws/src/lab1_pkg mkdir -p scripts nano scripts/talker.py

need to install nano first (good for beginners) apt update && apt install nano -y

back to talker.py nano scripts/talker.py

editor pops up, code: #!/usr/bin/env python3 import rclpy from rclpy.node import Node from ackermann_msgs.msg import AckermannDriveStamped

class Talker(Node): def init(self): super().init(‘talker’) self.declare_parameter(‘v’, 0.0) self.declare_parameter(‘d’, 0.0) self.publisher = self.create_publisher(AckermannDriveStamped, ‘drive’, 10) self.timer = self.create_timer(0.1, self.timer_callback)

def timer_callback(self):
    msg = AckermannDriveStamped()
    msg.drive.speed = self.get_parameter('v').value
    msg.drive.steering_angle = self.get_parameter('d').value
    self.publisher.publish(msg)

def main(args=None): rclpy.init(args=args) node = Talker() rclpy.spin(node) node.destroy_node() rclpy.shutdown()

if name == ‘main’: main()

ctrl+x, y, enter for save for rights: chmod +x scripts/talker.py

explanation: required Deliverable 2: talker node creation AckermannDriveStamped message publishing in drive topic v parameter → speed field d parameter → steering_angle field

code: Node class inheritence - ROS2 node creation declare_parameter - v, d parameter declaration create_publisher - publisher creation in drive topic timer_callback - message per 0.1 second

[creating relay node] nano scripts/relay.py

#!/usr/bin/env python3 import rclpy from rclpy.node import Node from ackermann_msgs.msg import AckermannDriveStamped

class Relay(Node): def init(self): super().init(‘relay’) self.subscription = self.create_subscription( AckermannDriveStamped, ‘drive’, self.listener_callback, 10) self.publisher = self.create_publisher(AckermannDriveStamped, ‘drive_relay’, 10)

def listener_callback(self, msg):
    new_msg = AckermannDriveStamped()
    new_msg.drive.speed = msg.drive.speed * 3.0                       #as lab1 guideline
    new_msg.drive.steering_angle = msg.drive.steering_angle * 3.0     #as lab1 guideline
    self.publisher.publish(msg)

def main(args=None): rclpy.init(args=args) node = Relay() rclpy.spin(node) node.destroy_node() rclpy.shutdown()

if name == ‘main’: main()

ctrl+x, y, then enter for save rights: chmod +x scripts/relay.py

[update before build] (make sure working in lab1_pkg directory with cd command) nano cMakeLists.txt

add this right above ament_package()

install(PROGRAMS scripts/talker.py scripts/relay.py DESTINATION lib/${PROJECT_NAME} )

ament_package()

[build] cd /lab1_ws colcon build source install/setup.bash

(opening Docker Again after VM reboot) docker start -i f1tenth_lab1

[Deliverable 3 making launch file] cd /lab1_ws/src/lab1_pkg mkdir -p launch nano launch/lab1_launch.py

from launch import LaunchDescription from launch_ros.actions import Node

def generate_launch_description(): return LaunchDescription([ Node( package=’lab1_pkg’, executable=’talker.py’, name=’talker’, parameters=[{‘v’: 1.0, ‘d’: 0.5}] ), Node( package=’lab1_pkg’, executable=’relay.py’, name=’relay’ ) ])

As lab1 guideline: Launching both nodes and setting talker node parameters

[update CMakeLists.txt: used for ROS2 build with code colcon build, define file’s install location and make Python script executable, without install() section the scripts will not be installed thus will not become executable] nano CMakeLists.txt

add codes below install(PROGRAMS

install(DIRECTORY launch DESTINATION share/${PROJECT_NAME} )

[build] cd /lab1_ws colcon build source install/setup.bash

[test launch file] ros2 launch lab1_pkg lab1_launch.py

after few error messages I found a typo, ‘parameter’ should be ‘parameters’ in the launch file also ‘pythond’ in talker.py should be ‘python’ and the indentations within python scripts should be made with ‘spaces’ not ‘tabs’ in ubuntu terminal

seems to be working, ran it in tmux for multiple terminals image

[ROS2 commands] commands need /, when it cannot find something but it is in there image

image

image

seems to be working with subscription and publishing, so I would like to move on to SUBMISSION.md

Lab 1: Intro to ROS 2 Written Questions Q1: During this assignment, you’ve probably ran these two following commands at some point: source /opt/ros/foxy/setup.bash and source install/local_setup.bash. Functionally what is the difference between the two? Answer:

Q2: What does the queue_size argument control when creating a subscriber or a publisher? How does different queue_size affect how messages are handled? Answer: The messages would be saved in the buffer for the maximum size of queue_size when the messages are not processed yet, and delete old ones when the queue_size is full. We could make it store more messages but it will require more memory space.

create_publisher(message type, topic, queue_size)

Q3: Do you have to call colcon build again after you’ve changed a launch file in your package? (Hint: consider two cases: calling ros2 launch in the directory where the launch file is, and calling it when the launch file is installed with the package.) Answer: We have to call colcon build when the launch file has to be copied from /src to /install So when we are launching in directory(/src) where the launch file is, colcon build is not needed, but when we are launching file in installed package, colcon build is necessary.