The Robot Operating System (ROS) is a middleware which allows subsystems to communicate with each other.
The ROS Wiki is found at http://wiki.ros.org/.
Roscore must be run before any node, and allows nodes to find each other by name, it acts similarly to how a DNS allows web clients to find web servers.
Only one roscore must be running in the system at any given time even across multiple machines. The machine that runs roscore is called the ROS master.
Through ROS, nodes can:
- exchange information with other nodes through message passing / pubsub on named topics
- be registered with the ROS master to communicate with other nodes on the system
The ROS filesystem is built out of metapackages, built out of packages, built out of a package manifest, messages, services, codes, and other miscellaneous things.
ROS Prerequisites
Don't use this, use Ultimate ROS 1+2 Setup Guide for Arch.
- Install
apptainer. (https://archlinux.org/packages/community/x86_64/apptainer/) - Install
ros-noetic-rospy. (https://aur.archlinux.org/packages/ros-noetic-rospy) You may want to use the arch4edu repository. - Download ROS container. (https://nextcloud.nms.kcl.ac.uk/s/NYskHat3eeFkgtA/download).
ROS Demo
Install prerequisites, then drop into the container and start roscore:
apptainer run ros-container.sif
roscoreRoscore should spit out information similar to:
auto-starting new master
process[master]: started with pid [38274]
ROS_MASTER_URI=http://furry:11311/
setting /run_id to b887ba54-3c17-11ed-91e2-309c231ba727
process[rosout-1]: started with pid [38295]
started core service [/rosout]
Roscore will use your hostname by default, so we have to point it in the right direction. Make sure /etc/hosts resolves your hostname!
Copy the ROS_MASTER_URI and then start new containers as such:
# start container with variable:
ROS_MASTER_URI=http://furry:11311/ apptainer run Applications/ros-container.sif
# or within a container:
export ROS_MASTER_URI=[..]Run the turtle simulator:
rosrun turtlesim turtlesim_node
Launch the ROS graph by using:
rosrun rqt_graph rqt_graph
Manipulate the ROS pubsub:
# list all topics
rostopic list
# show information about a topic
rostopic info /turtle1/pose
# subscribe to a topic
rostopic echo /turtle1/poseAfter subscribing to a ROS topic, you refresh the graph to see the new connection between turtle1 and you:

Manipulate the turtle:
# understand how we can move the turtle
rostopic info /turtle1/cmd_vel
# we receive the output:
# Type: geometry_msgs/Twist
# publish a message to the turtle
rostopic pub /turtle1/cmd_vel <double tap TAB>
# or copy and fill as below:
rostopic pub /turtle1/cmd_vel geometry_msgs/Twist "linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 2.0"Linux File Permissions
Create a sample executable script, i.e. my_script.sh, then:
# set all executable bits (user, group, others)
chmod +x my_script.sh
# set executable bit for the user
chmod u+x my_script.sh
# set executable bit for the group
chmod g+x my_script.sh
# set executable bit for others
chmod o+x my_script.sh
# remove executable bit from everyone
chmod -x my_script.sh
# set (rwx) read-write-execute for owner
# set (r-x) read-execute for group
# set (r--) read for others
chmod 754 my_script.shInteract from Python
Below is a sample script to create and publish to a new topic:
#!/usr/bin/env python3
import rospy
from std_msgs.msg import String
def run():
pub = rospy.Publisher('abc', String, queue_size=10)
rospy.init_node('pythonnode', anonymous=True)
rate = rospy.Rate(10) # 10hz
while not rospy.is_shutdown():
msg = "hello!"
pub.publish(msg)
rate.sleep()
if __name__ == '__main__':
try:
run()
except rospy.ROSInterruptException:
passRun the script as follows:
/opt/ros/noetic/env.sh python my_script.pyYou can listen to the topic as follows:
rostopic echo /abcInteract from Node.js
You can use rosnodejs to interact with ROS:
const rosnodejs = require('rosnodejs');
rosnodejs
.initNode('/rosnodejs')
.then(() => {
const pub = rosnodejs
.nh
.advertise('/abc', 'std_msgs/String');
const data = "Hello from Node.js!";
setInterval(() => {
pub.publish({ data });
}, 500);
});Run as follows: (URI has to be explicitly defined)
ROS_MASTER_URI=http://furry:11311/ /opt/ros/noetic/env.sh node test.jsAnd again, listen to the topic:
rostopic echo /abcInteract from Rust
To get started with Rust, create a new project and add the following dependencies:
# ROS library
rosrust = "0.9"
# automatic message generation
rosrust_msg = "0.1"Next, replace the src/main.rs file with:
fn main() {
// Initialize node
rosrust::init("rustnode");
// Create publisher
let publisher = rosrust::publish(
"abc", 100).unwrap();
// Create object that maintains 10Hz
// between sleep requests
let rate = rosrust::rate(10.0);
// Breaks when a shutdown signal is sent
while rosrust::is_ok() {
// Create string message
let mut msg = rosrust_msg::std_msgs::String::default();
msg.data = "Hello from Rust!".to_owned();
// Send string message to topic via publisher
publisher.send(msg).unwrap();
// Sleep to maintain 10Hz rate
rate.sleep();
}
}To build or run, you must provide the ROS environment:
# build
/opt/ros/noetic/env.sh cargo build
# run
/opt/ros/noetic/env.sh cargo run
# run w/o env (RLS may trigger recompile often)
target/debug/your-binaryAs usual, listen to /abc.