ROS Basics

Posted by baze on Mon, 03 Jan 2022 00:18:13 +0100

working space

src code space

build compilation space

devel development space

Install install control

Create workspace

The workspace is created by catkin in the src directory_ init_ workspace

mkdir -p ~/catkin_ws/src 	// Create directory - p create multi-level directory in one row
cd ~/catkin_ws/src			// Switch to ~ / catkin_ws/src 	  Directory
catkin_init_workspace		// Initialize workspace

Compile workspace

The compilation workspace should be in the root directory

cd ~/catkin_ws/				// Switch to workspace root
catkin_make					// compile

Setting environment variables

Only valid setting methods in the current terminal

source devdl/setup.bash		// This step is performed under the root directory

Determines whether the current environment variable is set successfully

echo $ROS_PACKAGE_PATH

output

/home/luo/ws/catkin_ws/src:/opt/ros/melodic/share

Environment variables are divided by: if your directory is in the environment variables, you can find that the added environment variables are in the front after the setting is successful.

Permanently effective method

In the previous method, the environment variable just set does not exist in the newly opened terminal. If you want the newly set environment variable to still exist in the newly opened terminal, you need to modify the environment variable in the ~ directory bashrc. The method is as follows

nano ~/.bashrc

Yes bashrc finally joined

source ~/ws/catkin_ws/devel/setup.bash
source ~/.bashrc				// Update environment variables

Verify whether the environment variable is set successfully, and open a new terminal,

echo $ROS_PACKAGE_PATH

Check whether there is a path you just added in the output path.

Filter useful information in environment variables

env |grep ROS_PACKAGE_PATH

Viewing environment variables and ROS_PACKAGE_PATH related information

Create Feature Pack

Create a function package under src

catkin_create_pkg learning_communication std_msgs rospy roscpp

Where catkin_create_pkg is an instruction

learning_communication is the name of the feature pack

std_msgs rospy roscpp depends on the environment and should be brought with it normally

Compile function pack

Return to the root directory

cd ..

compile

catkin_make

Note: the same function package cannot exist in the same workspace

The same function package can exist in different workspaces

Find Feature Pack

rospack find roscpp_tutorials

Returns the path of the feature pack

ROS communication mechanism

1. Topic programming

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-RjiF89gD-1640778615234)(D: \ notes folder \ ROS Foundation (2). assets\image-20211229105628607-16407466072741.png)]

  1. Create publisher

  2. Create subscriber

  3. Add compilation options

  4. Run executable

Create publisher

/**
 * This routine will publish chatter topic with message type String
 */
 
#include <sstream>
#include "ros/ros.h"
#include "std_msgs/String.h"

int main(int argc, char **argv)
{
  // ROS node initialization
  ros::init(argc, argv, "talker");
  
  // Create node handle
  ros::NodeHandle n;
  
  // Create a Publisher, publish topic named chatter, and the message type is std_msgs::String
  ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);

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

  int count = 0;
  while (ros::ok())
  {
	// Initialize std_msgs::String type message
    std_msgs::String msg;
    std::stringstream ss;
    ss << "hello world " << count;
    msg.data = ss.str();

	// Release news
    ROS_INFO("%s", msg.data.c_str());
    chatter_pub.publish(msg);

	// Loop waiting callback function
    ros::spinOnce();
	
	// Delay according to cycle frequency
    loop_rate.sleep();
    ++count;
  }

  return 0;
}

CMakeLists.txt file modification

The production executable file talker is generated to / talker under the name devel/lib/node, and then executed through rosrun

add_executable(talker src/talker.cpp)

If a third-party plug-in is used in cpp, you need to target it here_ Link links to a third-party library file. Now the linked library is the basic library of catkin

 target_link_libraries(talker  ${catkin_LIBRARIES} )

Create recipient

Write your own program

#include "ros/ros.h"
#include "std_msgs/String.h"


void  chatterCallback(const std_msgs::String::ConstPtr& msg)
{
    ROS_INFO("I heard : %s",msg->data.c_str());
}


int main(int argc, char **argv)
{
   ros::init(argc,argv,"lensener");
   ros::NodeHandle n;

   ros::Subscriber sub = n.subscribe("chatter1",1000,chatterCallback);

    ros::spin();


    return 0;
}

Program history

/**
 * This routine will subscribe to chatter topic, and the message type is String
 */
 
#include "ros/ros.h"
#include "std_msgs/String.h"

// After receiving the subscribed message, it will enter the message callback function
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  // Print the received message
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}

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

  // Create node handle
  ros::NodeHandle n;

  // Create a Subscriber, subscribe to topic named chatter, and register the callback function chatterCallback
  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);

  // Loop waiting callback function
  ros::spin();

  return 0;
}

CMakeLists.txt file modification

The production executable file talker is generated to / talker under the name devel/lib/node, and then executed through rosrun

add_executable(lensener src/lensener.cpp)

If a third-party plug-in is used in cpp, you need to target it here_ Link links to a third-party library file. Now the linked library is the basic library of catkin

 target_link_libraries(lensener  ${catkin_LIBRARIES} )

Problems here:

When you start subscribe first and then Publisher, the first two packets of published information will be discarded. What is the reason?

  1. Define msg file
  2. Then package Add function package dependency to XML
  3. Cmakelist Txt

Custom message structure

  1. Create a new msg folder under the feature pack

    New file person msg

    string name
    uint8 sex
    uint8 age
    
    uint8 unknown = 0
    uint8 male =1
    uint8 female =2
    
  2. In package Add in XML

      <build_depend> message_generation</build_depend>
      <exec_depend>message_runtime</exec_depend>
    
  3. CMakeList added

    1. find_package(catkin REQUIRED COMPONENTS
        roscpp
        rospy
        std_msgs
        message_generation
      )
      
    2. ## Generate messages in the 'msg' folder
      add_message_files(
        FILES
        Person.msg
        # Message2.msg
      )
      
    3. ## Generate added messages and services with any dependencies listed here
      generate_messages(
        DEPENDENCIES
        std_msgs
      )
      
    4. catkin_package(
      #  INCLUDE_DIRS include
      #  LIBRARIES learning_communication
       CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
      #  DEPENDS system_lib
      )
      

      After the creation is completed, the compilation can be performed through

      rosmsg show Person To verify that the was created correctly
      

2. Service programming

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-0t52qGJO-1640778615236)(D: \ notes folder \ ROS Foundation (2). assets\image-20211229153801254-16407634850601.png)]

  1. Create server
  2. Create client
  3. Add compilation options
  4. Run executable

Define srv file

  1. Define srv file

  2. In package Add function package dependency to XML

      <build_depend> message_generation</build_depend>
      <exec_depend>message_runtime</exec_depend>
    
  3. In cmakelist Txt is the same as modifying and adding custom compilation dependencies 1 and 2. 3 is unique

  4. find_package(catkin REQUIRED COMPONENTS
      roscpp
      rospy
      std_msgs
      message_generation
    )
    
  5. catkin_package(
    #  INCLUDE_DIRS include
    #  LIBRARIES learning_communication
     CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
    #  DEPENDS system_lib
    )
    
  6. ## Generate services in the 'srv' folder
    add_service_files(
      FILES
      AddTwo.srv
      # Service2.srv
    )
    
  7. Generate supportable files

    add_executable(server src/server.cpp)
    
  8. Test whether the generated file is available

    Start roscore rosrun

be careful

Programming in vscode. In order to introduce the new srv file during the programming process, you need to enter the new srv file in Src / vscode/c_ cpp_ properties. Add under includePath in JSON file

    "includePath": [
        "/opt/ros/melodic/include/**",
        "/home/luo/ws/catkin_ws/src/learning_communication/include/**",
        "/usr/include/**",
        "/home/luo/ws/catkin_ws/devel/include/learning_communication**"				// This line is newly added and contains the newly generated srv file
      ],

Create a server

  1. Initialize ROS node
  2. Create Server instance
  3. The loop waits for the service request and enters the callback function
  4. Complete the processing of the service function in the callback function and feed back the response data
#include "ros/ros.h"
#include "learning_communication/AddTwo.h"

// service callback function, input parameter req, output parameter res
bool add(learning_communication::AddTwo::Request  &req,
         learning_communication::AddTwo::Response &res)
{
  // Add the request data in the input parameters and put the result into the response variable
  res.sum = req.a + req.b;
  ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
  ROS_INFO("sending back response: [%ld]", (long int)res.sum);
  
  return true;
}

int main(int argc, char **argv)
{
  	// ROS node initialization
    ros::init(argc,argv,"add_two_inis_server");
    
	// Create node handle
    ros::NodeHandle n;
	
	// Create a file named add_ two_ The server of ints registers the callback function add()
    ros::ServiceServer service = n.advertiseService("add_two_inis",add);
	
	// Loop waiting callback function
    ROS_INFO("Ready to add two ints.");
    ros::spin();

    return 0;
}

Client program

#include "learning_communication/AddTwo.h"
#include "ros/ros.h"
#include <cstdlib>

int main(int argc, char **argv)
{
    // ROS node initialization
    ros::init(argc,argv,"add_two_ints_client");
    
    // Get two addends from the terminal command line
    if (argc !=3)
    {
        ROS_INFO("usage :add two ints client X Y");
        return 1;
    }
    
    // Create node handle
    ros::NodeHandle n;
    
	// Create a client and request add_two_int service. The service message type is learning_communication::AddTwoInts
    ros::ServiceClient client = n.serviceClient<learning_communication::AddTwo>("add_two_inis_server");
	
	// Create learning_ Communication:: service message of type addtwoints
    learning_communication::AddTwo srv;
    srv.request.a = atoll(argv[1]);
    srv.request.b = atoll(argv[2]);

	// Issue a service request and wait for the response result of the addition operation
    if(client.call(srv))
    {
        ROS_INFO("Sum: %ld",(long int)srv.response.sum);
    }
    else
    {
        ROS_INFO("Failed to call service add_ two_ints");
        return 1;
    }
    return 0;
}

Compile code

add_executable(server src/server.cpp)						// Compile code to generate executable
target_link_libraries(server  ${catkin_LIBRARIES} )			// Set up link library
add_dependencies(server ${PROJECT_NAME}_gencpp)				// server needs to add an additional sentence to set dependency

add_executable(client src/client.cpp)
target_link_libraries(client  ${catkin_LIBRARIES} )
add_dependencies(client ${PROJECT_NAME}_gencpp)				

Topics: Machine Learning