-Linux Commands
-During class we went over a number of basic Linux commands. Open a terminal on the Master and let’s practice using those commands (use the shortcut ctrl+alt+t
to open a new terminal window or select an open terminal and hit ctrl+shift+t
to open a new terminal tab).
-When observing the terminal (or Shell) you will note the syntax username@hostname:
(i.e., on the master: dfec@masterX:
, on the robot: pi@robotX
), the current working directory (i.e., ~
, which represents the home folder of the user), and lastly the ‘$’ character and a blinking cursor. This line is the prompt and the blinking cursor indicates the terminal is active and ready for commands.
-Run the commands to move to the home folder and make a new directory:
-cd
-mkdir my_folder
-
-💡️ Tip: In Linux, if you highlight a command you can paste it into the terminal by clicking the scroll wheel.
-
-Change directories into your new folder:
-cd my_folder
-Create a new bash script we can use to drive the TurtleBot3:
-touch move_turtlebot.sh
-A bash script is a regular text file that allows you to run any command you would run within the terminal. We will use it to run a few ROS command line tools to move our TurtleBot.
-We can use the Nano text editor to edit a file within the terminal. There are a number of text editors within the terminal and WWIII might be fought over which is best; some other options include Vim and Emacs. Nano is one of the more simple editors for quick edits. Feel free to use whichever works best for you, but all guidance within this course will be based on Nano.
-Edit the new bash script:
-nano move_turtlebot.sh
-Copy the following into the script:
-#!/bin/bash
-
-ARG1=$1
-
-if [ $ARG1 == 'forward' ]; then
- rostopic pub /cmd_vel geometry_msgs/Twist "linear:
- x: 0.15
- y: 0.0
- z: 0.0
-angular:
- x: 0.0
- y: 0.0
- z: 0.0"
-
-elif [ $ARG1 == 'rotate' ]; then
- rostopic pub /cmd_vel geometry_msgs/Twist "linear:
- x: 0.0
- y: 0.0
- z: 0.0
-angular:
- x: 0.0
- y: 0.0
- z: 0.5"
-
-elif [ $ARG1 == 'stop' ]; then
- rostopic pub /cmd_vel geometry_msgs/Twist "linear:
- x: 0.0
- y: 0.0
- z: 0.0
-angular:
- x: 0.0
- y: 0.0
- z: 0.0"
-else
-echo "Please enter one of the following:
- forward
- rotate
- stop"
-fi
-
-
-Typing ctrl+s
saves the file and then typing ctrl+x
exits Nano.
-Again, a bash script just runs commands exactly as you would within a terminal. The above code takes an argument and publishes a Twist message over the /cmd_vel topic to drive the robot accordingly.
-Before running this script, let’s get our ROS environment setup:
-
-Open a new terminal and type roscore
.
-Open a new terminal tab and run our TurtleBot3 simulation:
-roslaunch turtlebot3_gazebo turtlebot3_empty_world.launch
-
-
-Now, in a new terminal, run the script you created:
-./move_turtlebot.sh
-Did you get an error? That is because the permissions have not been properly set and you do not have execute permissions. You can observe the permissions of a file by typing ls -la
.
-For the move_turtlebot.sh
file you should see -rw-rw-r--
. The first position indicates file type (‘d’ for directory, ‘-’ for regular file), the next three positions indicate read (r), write (w), and execute (x) permissions for the file owner (u), the next three indicate permisions for the group owner of the file (g), and the last three characters indicate permissions for all other users (o).
-You can change the permissions of a file or directory using the command chmod
:
-
-⌨️ Syntax: chmod <groups to assign the permissions><permissions to assign/remove> <file/folder>
-
-For example, if we wanted to give the Owner execute permissions, you can enter the command:
-chmod u+x move_turtlebot.sh
-Typically we will give all users executable permissions (chmod +x move_turtlebot.sh
). This isn’t the most secure thing to do, but in our controlled environment, it isn’t an issue. If you type ls -la
now you should see the ‘x’ permission added for each permission group (-rwxrwxr-x
).
-Try running your script again:
-./move_turtlebot.sh rotate
-
-📝️ Note: You can remove permissions by utilizing the ‘-’ character instead of ‘+’.
-
-Move to your github repo that you previously created:
-cd ~/master_ws/src/ece387_master_sp23-USERNAME/master/
-Now we are going to create a new ROS package. You learned this in the previous homework assignment, but we will continue practicing:
-catkin_create_pkg module02 std_msgs rospy roscpp
-Before we go any further, it is always a good idea to compile your workspace with the new package. To do that, we will use a command catkin_make
from within the top-level of the workspace:
-cd ~/master_ws
-catkin_make
-Now go back to the my_folder
that you created at the beginning of the lesson and create a new bash script, bash_script.sh
, to accomplish the following:
-
-Moves into the package you just created (you will need to figure out the complete path to this folder)
-Creates a directory called my_scripts
-Moves into that directory
-Creates a file called move_turtlebot_square.py
-Lists all files showing the permissions
-Modifies the permissions of the move_turtlebot_square.py file so all groups have executable permissions
-Lists all files again showing the updated permissions
-
-Now run the script. If successful you should see the file listed without and then with execute permissions.
-We are done with this script so let’s remove it (you will need to either use the complete path to the file you want to remove, or be in the directory of the file you want to remove). The rm
command can remove folders or files. If you want to learn more about a command there are two helpful tools: Help: rm --help
; Manual: man rm
.
-Type the following to remove our bash script:
-rm bash_script.sh
.
-
-
Note
-
To delete a whole folder add the -r
tag to remove directories and thier contents recursively (e.g., rm -r my_folder
, but don’t remove your folder just yet).
-
-We can copy (cp
, just like ctrl+c in a GUI) and move (mv
, just like ctrl+x in a GUI) files and folders as well. Let’s copy the move_turtlebot.sh
to the my_scripts
folder you created earlier:
-cp move_turtlebot.sh ~/master_ws/src/ece387_master_sp23-USERNAME/master/module02/my_scripts
-
-⌨️ Syntax: cp <source> <destination>
-
-
-
Note
-
For the above to work, you must already be in the same folder as the move_turtlebot.sh
file. Otherwise you have to use the absolute file path, such as ~/my_folder/move_turtlebot.sh
.
-
-You can now delete your my_folder
folder.
-cd ..
-rm -r my_folder
-Change directories to your my_scripts
folder. We can use a ROS tool, roscd
, to change directories to ROS packages without using the absolute file path:
-roscd module02/my_scripts
-
-⌨️ Syntax: roscd <package/folder>
-
-Edit the move_turtlebot_square.py file and paste the following contents:
-#!/usr/bin/env python3
-import rospy, time, math
-from geometry_msgs.msg import Twist
-
-class MoveTurtleBot():
- def __init__(self):
- self.pub = rospy.Publisher('cmd_vel', Twist, queue_size=1)
- self.cmd = Twist()
- self.ctrl_c = False
- rospy.on_shutdown(self.shutdownhook)
- self.rate = rospy.Rate(10) # 10 Hz
-
- def publish_cmd_vel_once(self):
- """
- In case publishing fails on first attempt
- """
- while not self.ctrl_c:
- connections = self.pub.get_num_connections()
- if connections > 0:
- self.pub.publish(self.cmd)
- rospy.loginfo("Cmd Published")
- break
- else:
- self.rate.sleep()
-
- def shutdownhook(self):
- rospy.loginfo("Shutting down. Stopping TurtleBot!")
- self.stop_turtlebot()
- self.ctrl_c = True
-
- def stop_turtlebot(self):
- self.cmd.linear.x = 0.0
- self.cmd.angular.z = 0.0
- self.publish_cmd_vel_once()
-
- def move_time(self, moving_time = 10.0, lin_spd = 0.2, ang_spd = 0.2):
- self.cmd.linear.x = lin_spd
- self.cmd.angular.z = ang_spd
-
- self.publish_cmd_vel_once()
- time.sleep(moving_time)
-
- def move_square(self):
- i = 0
-
- while not self.ctrl_c:
- # Move Forward
- self.move_time(moving_time = 2.0, lin_spd = 0.2, ang_spd = 0)
- # Turn
- ang_spd = 0.5 # rad/sec
- moving_time = math.radians(90)/ang_spd
- self.move_time(moving_time = moving_time, lin_spd = 0.0, ang_spd = ang_spd)
-
-
-if __name__ == '__main__':
- rospy.init_node('move_turtlebot')
- move_object = MoveTurtleBot()
- try:
- move_object.move_square()
- except rospy.ROSInterruptException:
- pass
-
-
-There is a lot going on in this script, but hopefully after the previous lesson some of it makes sense. To summarize, the script creates a node, move_turtlebot
, that publishes Twist messages to the /cmd_vel topic to drive the robot in a square: drive forward, turn 90 degrees, drive forward, repeat. This script will run until killed using ctrl+c
.
-The script is already executable, so you can run it using ROS!
-rosrun module02 move_turtlebot_square.py
-
-
Note
-
Note:** It won’t be a perfect square as the robot doesn’t turn perfectly, but it will be close!
-
-The robot is now driving in a square until the script is killed. If you select the terminal and hit ctrl+c
, it will kill the script.
-Run the script again and this time hit ctrl+z
. You can see that the robot is still running, but the commands are not updating. This is because ctrl+z
suspends the current process, but does not kill it. We can observe all running processes on Linux by typing ps -faux
. As you can see, there are a lot! The grep
command allows us to filter these processes. Try the following:
-ps -faux | grep move_turtlebot_square.py
-The first entry should be our process and the leftmost number is the process ID (PID). We can kill any process using this number and the kill
command:
-kill PID
replacing PID with the number listed.
-If you hit enter again, you should see that the process was killed. Unfortunately, the TurtleBot will just continue to execute the last command sent, so you need to kill the simulation as well. Just select that terminal and hit ctrl+c
.
-The grep
tool is very powerful and can be used with any Linux command. For example, if you wanted to see all turtlebot packages available to us, we could type the following:
-rospack list
-There are a lot, so this isn’t very helpful, but we can filter this command!
-rospack list | grep turtlebot
-The vertical line, ‘|’, pipes the results of the first command into the second command, so we can filter all packages looking only for turtlebot packages.
-
-