ROS Learning Notes - Installation and Basic Usage of ROS

ROS Installation

  • Using the rosdep init and rosdep update commands is very slow and often fails, even if it's a scientific Internet connection, according to the official method.So we install ROS by downloading the source code and modifying the file installation address
  • Specific process reference ROS Installation

ROS Basic Grammar

1. Creation of workspaces

(1) Create and initialize workspaces

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace

(2) Compile the workspace and generate the installation space

cd ~/catkin_ws/
catkin_make
catkin_make install

(3) Setting environment variables

source devel/setup.bash

(4) Check environment variables

echo $ROS_PACKAGE_PATH

2. Create a feature pack

(1) Create feature packs

cd ~/catkin_ws/src
catkin_create_pkg <package_name> [depend1] [depend2] [depend3]

(2) Compile functional packages

 cd ~/catkin_ws
 catkin_make
 source ~/catkin_ws/devel/setup.bash
  • Feature packages with the same name are not allowed in the same workspace.
  • Feature packages with the same name are allowed in different workspaces.

3. Topics

(1) Create Publisher

(1) Write publisher code

(2) Configuration

​ C++

i. Adding written code files to the **** file for developing the Feature Pack

ii. Configuration Feature Pack **<CMakeLists.txt>**File

  • Setting up code to compile and executable files to generate
  • Set Link Library
#Example
add_executable(velocity_publisher src/velocity_publisher.cpp)
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})

​ python

i. Adding written code files to the **** file for developing the Feature Pack

(3) Compile and run

i. Compilation

 cd ~/catkin_ws
 catkin_make
 source devel/setup.bash

ii. Run

#Take the little turtle for example 
roscore rosrun turtlesim turtlesim_node #C++ 
rosrun learning_topic velocity_publisher #python 
rosrun learning_topic velocity_publisher.py

C++ code sample

/**
 * This routine will publish turtle1/cmd_VelTopic, message type geometry_msgs::Twist
 */

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>

int main(int argc, char **argv)
{
    /* ROS Node Initialization */
    ros::init(argc, argv, "velocity_publisher");

    /* Create node handle */
    ros::NodeHandle n;

    /* Create a Publisher and publish it as / turtle1/cmd_vel topic, message type geometry_msgs::Twist, queue length 10*/
    ros::Publisher turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);

    /* Set the frequency of the cycle */
    ros::Rate loop_rate(10);

    int count = 0;
    while (ros::ok())
    {
        /* Initialize geometry_Msgs:: Messages of type Twist */
        geometry_msgs::Twist vel_msg;
        vel_msg.linear.x = 0.5;
        vel_msg.angular.z = 0.2;

        /* Publish a message */
        turtle_vel_pub.publish(vel_msg);
        ROS_INFO("Publsh turtle velocity command[%0.2f m/s, %0.2f rad/s]", 
                vel_msg.linear.x, vel_msg.angular.z);

        /* Delay by cycle frequency */
        loop_rate.sleep();
    }

    return 0;
}

python code example

# This routine will publish turtle1/cmd_VelTopic, message type geometry_msgs::Twist

import rospy
from geometry_msgs.msg import Twist

def velocity_publisher():
    # ROS Node Initialization
    rospy.init_node('velocity_publisher', anonymous=True)

    # Create a Publisher and publish it as / turtle1/cmd_vel topic, message type geometry_msgs::Twist, queue length 10
    turtle_vel_pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)

    #Set the frequency of the cycle
    rate = rospy.Rate(10) 

    while not rospy.is_shutdown():
        # Initialize geometry_Msgs:: Messages of type Twist
        vel_msg = Twist()
        vel_msg.linear.x = 0.5
        vel_msg.angular.z = 0.2

        # Publish a message
        turtle_vel_pub.publish(vel_msg)
        rospy.loginfo("Publsh turtle velocity command[%0.2f m/s, %0.2f rad/s]", 
                vel_msg.linear.x, vel_msg.angular.z)

        # Delay by cycle frequency
        rate.sleep()

if __name__ == '__main__':
    try:
        velocity_publisher()
    except rospy.ROSInterruptException:
        pass

(2) Create Subscriber

  • The creation process is the same as Publisher

C++ code sample

/**
 * This routine will subscribe to/turtle1/pose topic, message type turtlesim::Pose
 */
 
#include <ros/ros.h>
#include "turtlesim/Pose.h"

/* When a subscribed message is received, it enters the message callback function */
void poseCallback(const turtlesim::Pose::ConstPtr& msg)
{
    // Print the received message
    ROS_INFO("Turtle pose: x:%0.6f, y:%0.6f", msg->x, msg->y);
}

int main(int argc, char **argv)
{
    /* Initialize ROS Node */
    ros::init(argc, argv, "pose_subscriber");

    /* Create node handle */
    ros::NodeHandle n;

    /* Create a Subscriber, subscribe to a topic named/turtle1/pose, and register the callback function poseCallback */
    ros::Subscriber pose_sub = n.subscribe("/turtle1/pose", 10, poseCallback);

    /* Loop Wait Callback Function */
    ros::spin();

    return 0;
}

python code example

# This routine will subscribe to/turtle1/pose topic, message type turtlesim::Pose

import rospy
from turtlesim.msg import Pose

def poseCallback(msg):
    rospy.loginfo("Turtle pose: x:%0.6f, y:%0.6f", msg.x, msg.y)

def pose_subscriber():
    # ROS Node Initialization
    rospy.init_node('pose_subscriber', anonymous=True)

    # Create a Subscriber, subscribe to a topic named/turtle1/pose, and register the callback function poseCallback
    rospy.Subscriber("/turtle1/pose", Pose, poseCallback)

    # Loop Wait Callback Function
    rospy.spin()

if __name__ == '__main__':
    pose_subscriber()

(3) Definition and use of topic messages

(1) Definition****File

i. Add a feature pack dependency in **<package.xml>**

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

ii. Add compilation options in **<CMakeLists.txt>**

#Example

#Add Dependent Package
find_package( ...... message_generation) catkin_package(CATKIN_DEPENDS ...... message_runtime)

#Execute.Msg files in the'msg'folder
add_message_files(FILES Person.msg)

#Associate official packages
generate_messages(DEPENDENCIES std_msgs)
  • find_package is a common macro in cmake that adds catkin attributes and other attributes to the current package
  • Catkin_The package macro defines the impact of the current package when called by another package

msg code example

string name
uint8  age
uint8  sex

uint8 unknown = 0
uint8 male    = 1
uint8 female  = 2

4. Services

(1) Create client Client

  • The configuration process refers to the topic above

C++ code sample

/**
 * This routine will request/spawn service, service data type turtlesim::Spawn
 */

#include <ros/ros.h>
#include <turtlesim/Spawn.h>

int main(int argc, char** argv)
{
    /* Initialize ROS Node */
    ros::init(argc, argv, "turtle_spawn");

    /* Create node handle */
    ros::NodeHandle node;

    /* Once the / span service is discovered, create a service client to connect to the service named / span */
    ros::service::waitForService("/spawn");
    ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");

    /* Initialize turtlesim::Spawn's request data */
    turtlesim::Spawn srv;
    srv.request.x = 2.0;
    srv.request.y = 2.0;
    srv.request.name = "turtle2";

    /* Request service calls */
    ROS_INFO("Call service to spwan turtle[x:%0.6f, y:%0.6f, name:%s]", 
             srv.request.x, srv.request.y, srv.request.name.c_str());

    add_turtle.call(srv);

    /* Show results of service calls */
    ROS_INFO("Spwan turtle successfully [name:%s]", srv.response.name.c_str());

    return 0;
};

python code example

# This routine will request/spawn service, service data type turtlesim::Spawn

import sys
import rospy
from turtlesim.srv import Spawn

def turtle_spawn():
    # ROS Node Initialization
    rospy.init_node('turtle_spawn')

    # Once the / span service is discovered, create a service client to connect to the service named / span
    rospy.wait_for_service('/spawn')
    try:
        add_turtle = rospy.ServiceProxy('/spawn', Spawn)

        # Request service calls, enter request data
        response = add_turtle(2.0, 2.0, 0.0, "turtle2")
        return response.name
    except rospy.ServiceException, e:
        print "Service call failed: %s"%e

if __name__ == "__main__":
    #Service Call and Display Call Result
    print "Spwan turtle successfully [name:%s]" %(turtle_spawn())

(2) Create a server

  • The configuration process refers to the topic above

C++ code sample

/**
 * This routine will execute/turtle_command service, service data type std_srvs/Trigger
 */
 
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <std_srvs/Trigger.h>

ros::Publisher turtle_vel_pub;
bool pubCommand = false;

/* service Callback function, input parameter req, output parameter res */
bool commandCallback(std_srvs::Trigger::Request  &req,
                     std_srvs::Trigger::Response &res)
{
    pubCommand = !pubCommand;

    /* Show request data */
    ROS_INFO("Publish turtle velocity command [%s]", pubCommand==true?"Yes":"No");

    /* Set up feedback data */
    res.success = true;
    res.message = "Change turtle command state!"

    return true;
}

int main(int argc, char **argv)
{
    /* ROS Node Initialization */
    ros::init(argc, argv, "turtle_command_server");

    /* Create node handle */
    ros::NodeHandle n;

    /* Create a name named/turtle_server of command, register callback function commandCallback */
    ros::ServiceServer command_service = n.advertiseService("/turtle_command", commandCallback);

    /* Create a Publisher and publish it as / turtle1/cmd_vel topic, message type geometry_msgs::Twist, queue length 10 */
    turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);

    /* Loop Wait Callback Function */
    ROS_INFO("Ready to receive turtle command.");

    /* Set the frequency of the cycle */
    ros::Rate loop_rate(10);

    while(ros::ok())
    {
        /* View callback function queue once */
        ros::spinOnce();
        
        /* If flagged true, issue speed instructions */
        if(pubCommand)
        {
            geometry_msgs::Twist vel_msg;
            vel_msg.linear.x = 0.5;
            vel_msg.angular.z = 0.2;
            turtle_vel_pub.publish(vel_msg);
        }

        /* Delay by cycle frequency */
        loop_rate.sleep();
    }

    return 0;
}

python code example

# This routine will execute/turtle_command service, service data type std_srvs/Trigger

import rospy
import thread,time
from geometry_msgs.msg import Twist
from std_srvs.srv import Trigger, TriggerResponse

pubCommand = False;
turtle_vel_pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)

def command_thread():    
    while True:
        if pubCommand:
            vel_msg = Twist()
            vel_msg.linear.x = 0.5
            vel_msg.angular.z = 0.2
            turtle_vel_pub.publish(vel_msg)
            
        time.sleep(0.1)

def commandCallback(req):
    global pubCommand
    pubCommand = bool(1-pubCommand)

    # Show request data
    rospy.loginfo("Publish turtle velocity command![%d]", pubCommand)

    # Feedback data
    return TriggerResponse(1, "Change turtle command state!")

def turtle_command_server():
    # ROS Node Initialization
    rospy.init_node('turtle_command_server')

    # Create a name named/turtle_server of command, register callback function commandCallback
    s = rospy.Service('/turtle_command', Trigger, commandCallback)

    # Loop Wait Callback Function
    print "Ready to receive turtle command."

    thread.start_new_thread(command_thread, ())
    rospy.spin()

if __name__ == "__main__":
    turtle_command_server()

(3) Definition and use of service data

i. Define the SRV file and place it in the **'srv'** folder

ii. The remaining configurations refer to the above **'Definition and Use of Topic Data'**

  • add_message_files(FILES Person.msg) —> add_service_files(FILES Person.srv)

srv code example

string name
uint8  age
uint8  sex

uint8 unknown = 0
uint8 male    = 1
uint8 female  = 2

---
string result
  • '-'is a data splitter line with Request data above and Response data below

Tags: Linux

Posted on Mon, 06 Sep 2021 12:02:01 -0400 by bender