yahboom
HomeLearn
Solution
Blog
Online Store
About Us
EN/中文
YDLIDAR 4ROS LiDAR📖
01.Linux basic course
  • 1.Introduction to Linux system
  • 2.Ubuntu file system
  • 3.Ubuntu common commands
  • 4.Ubuntu common editors
  • 5.Ubuntu software operation commands
  • 6.Virtual machine installation
  • 7.SSH remote control
  • 8.VNC remote control
  • 9.Transfer files remotely
  • 10.Driver library and communication
  • 11.Static IP and hotspot mode
  • 12.Bind device ID
  • 13.Capacity expansion and resource allocation
  • 14.Update system software sources
  • 15.Set root user password
  • 16.sudo free password
  • 17.Connect to WiFi network
  • 18.View system version
  • 19.Customized service management
  • 20.Back up system image
02.ROS1 basic course
  • 1.ROS introduction
  • 2.ROS installation
  • 3.ROS common command tools
  • 4.ROS workspace
  • 5.ROS function package
  • 6.ROS node
  • 7.ROS topic publisher
  • 8.ROS topic subscribers
  • 9.ROS service client
  • 10.ROS service server
  • 11.ROS action client
  • 12.ROS action server
  • 13.ROS custom message reception
  • 14.ROS-launch file
  • 15.ROS-TF transformation
  • 16.ROS parameter service
  • 17.ROS-rviz use
  • 18.ROS-rqt tool usage
  • 19.Topic message recording and playback
  • 20.urdf model introduction
  • 21.gazebo introduction
  • 22.ROS distributed communication
03.ROS1 lidar course
  • 0.Instructions before use
  • 1.Preparation
  • 2.Handheld lidar mapping
  • 3.Lidar avoiding
  • 4.Lidar guard
  • 5.Lidar follow
  • 6.Lidar mapping
  • 7.rrt_exploration mapping algorithm
  • 8.Navigation
  • 9.APP Mapping and Navigation
  • 10.RTAB 3D mapping and navigation
04.ROS2 basic course
  • 1. Introduction to ROS2
  • 2.ROS2 install Humble
  • 3.ROS2 development environment
  • 4.ROS2 workspace
  • 5.ROS2 function package
  • 6.ROS2 node
  • 7.ROS2 topic communication
  • 8.ROS2 service communication
  • 9.ROS2 action communication
  • 10.ROS2 custom interface message
  • 11.ROS2 parameter service case
  • 12.ROS2 meta-function package
  • 13.ROS2 distributed communication
  • 14.ROS2 DDS
  • 15.ROS2 time related API
  • 16.ROS2 common command tools
  • 17.ROS2 rviz2 use
  • 18.ROS2 rqt toolbox
  • 19.ROS2 Launch startup file configuration
  • 20.ROS2 recording and playback tool
  • 21.ROS2 URDF model
  • 22.ROS2 Gazebo simulation platform
  • 23.ROS2 TF2 coordinate transformation
05.ROS2 lidar course
  • 0.ReadMe
  • 1.Preparation
  • 2.Handheld lidar mapping
  • 3.Lidar avoiding
  • 4.Lidar follow
  • 5.Lidar guard
  • 6.Lidar patrol
  • 7.gmapping mapping
  • 8.cartographer mapping
  • 9.Navigation and avoiding
  • 10.APP Mapping and Navigation
  • 11.RTAB 3D mapping and navigation
06.RPi 5 Docker course
  • 1.Overview and installation
  • 2.Common commands
  • 3.Understand and publish images
  • 4.Hardware interaction data processing
  • 5.Enter docker container
  • 6.Update docker images
  • 7.Docker container to install ROS using accessories
Download
  • ROS1-Code
  • ROS1-VMFile
  • ROS2-Code
  • ROS2-VMFile
  • Other File
  • ROS2_Basic_VM
Download ZIP

Welcome to YDLIDAR 4ROS LiDAR repository

11.ROS action client

11.ROS action client

11.1 action overview

Action is a commonly used communication method in ros. There is an action client and an action server. It should be mentioned here that action and servcie are both communication methods with feedback, so what is the difference between them? An obvious difference is that action can feedback the current status at a certain frequency, while service can only feedback once.This is a very important point. For example, when executing a long-term task, you can use the action communication method to check the progress at any time, and you can also terminate the request.

11.2 action communication principle

Let’s look at the picture of ros-wiki,

image-20231026111456240

Here it shows that the client sends a goal, which is sendGoal, and the server executes the corresponding program after receiving it, which is excuteGoal. This is a simple process, but in it, the client may also send feedback instructions according to the set frequency, and the server will send the feedback results back to the client after receiving it.

There are a few important concepts to know here:

  • Goal

    When a robot performs an action, it should have clear moving target information, telling the server "where I want to go" or "what I want to do", including some parameter settings, direction, angle, speed, etc. This enables the robot to complete action tasks.

  • Feedback

    During the action, the server should feed back real-time status information to the client, telling the client "where are we now" or "where have I done". It is also convenient for the client to choose to continue or give other instructions.

  • Result

    When the movement is completed, the server sends the result data to the client, telling the client "I have arrived now" or "I have completed the action now", so that the client can obtain all the information of this action.For example, it may include the robot's movement duration, final posture, etc.

image-20231026114424613

11.3 action file

Behavior specifications use .action files. The .action file has the goal definition, then the result definition, then the feedback definition, with each part separated by 3 hyphens (---). In the src directory of the workspace, create a new learn_action function package and enter the following instructions:

catkin_create_pkg learn_action std_msgs rospy roscpp actionlib actionlib_msgs

Then go back to the workspace to compile,

xxxxxxxxxx
cd ~/ros_ws
catkin_make

Then create a new folder under the learn_action folder, named action, to store the .action file we defined and input from the terminal.

xxxxxxxxxx
cd ~/ros_ws/src/learn_action
mkdir action

In the action folder, create a new file named DoDishes.action and copy the following code into it.

xxxxxxxxxx
# Define the goal
uint32 dishwasher_id  # Specify which dishwasher we want to use
---
# Define the result
uint32 total_dishes_cleaned
---
# Define a feedback message 
float32 percent_complete

Modify the CMakeLists.txt file to the following content,

xxxxxxxxxx
find_package(catkin REQUIRED COMPONENTS
  actionlib
  actionlib_msgs
  roscpp
  rospy
  std_msgs
  genmsg
)
add_action_files(
   DIRECTORY
   action
   FILES
   DoDishes.action
)
generate_messages(
   DEPENDENCIES
   actionlib_msgs
 )

Then, we go back to the workspace to compile and enter in the terminal,

xxxxxxxxxx
cd ~/ros_ws
catkin_make

After successful compilation, for DoDishes.action, the following message is generated through genaction.py to generate the relevant msg file, which can be seen through rosmsg list and entered in the terminal,

xxxxxxxxxx
rosmsg list

image-20231026120635055

As shown in the figure above, it is the msg file related to the generated DoDishes.action.

11.4 Write action client code

Under the learn_action function package, create a new file named action_client.cpp and copy the following content into it.

​x
#include <actionlib/client/simple_action_client.h>
#include "learn_action/DoDishesAction.h"

typedef actionlib::SimpleActionClient<learn_action::DoDishesAction> Client;

// When the action is completed, the callback function will be called once
void doneCb(const actionlib::SimpleClientGoalState& state,
        const learn_action::DoDishesResultConstPtr& result)
{
    ROS_INFO("Yay! The dishes are now clean");
    ros::shutdown();
}

// When the action is activated, the callback function will be called once.
void activeCb()
{
    ROS_INFO("Goal just went active");
}

// Callback function called after receiving feedback
void feedbackCb(const learn_action::DoDishesFeedbackConstPtr& feedback)
{
    ROS_INFO(" percent_complete : %f ", feedback->percent_complete);
}

int main(int argc, char** argv)
{
    ros::init(argc, argv, "do_dishes_client");

    // Define a client
    Client client("do_dishes", true);

    // Waiting for server side
    ROS_INFO("Waiting for action server to start.");
    client.waitForServer();
    ROS_INFO("Action server started, sending goal.");

    // Create an action goal
    learn_action::DoDishesGoal goal;
    goal.dishwasher_id = 1;

    // Send the action goal to the server and set the callback function
    client.sendGoal(goal,  &doneCb, &activeCb, &feedbackCb);

    ros::spin();

    return 0;
}

Modify CMakeLists.txt file and add the following content,

xxxxxxxxxx
add_executable(action_client src/action_client.cpp)
target_link_libraries( action_client ${catkin_LIBRARIES})
add_dependencies(action_client ${${PROJECT_NAME}_EXPORTED_TARGETS})

Return to the workspace to compile,

xxxxxxxxxx
cd ~/ros_ws
catkin_make

After the compilation is completed, reopen the terminal or source, and then enter the following command to run,

xxxxxxxxxx
rosrun learn_action action_client

image-20231026122446332

Because the server is not running, no corresponding services are provided, or corresponding actions and feedback are performed. In the next section, we learn how to write the server side of the action. Let's look at the core code now.

xxxxxxxxxx
// Define a client
Client client("do_dishes", true);

Here we first define a client with two pieces of information. The first is that the service sought by the client is "do_dishes", and the second is true which means starting a thread to provide services for the subscription of this operation.

xxxxxxxxxx
client.waitForServer();

Waiting for the "do_dishes" service to start

xxxxxxxxxx
learn_action::DoDishesGoal goal;
goal.dishwasher_id = 1;
// Send the action goal to the server and set the callback function
client.sendGoal(goal,  &doneCb, &activeCb, &feedbackCb);

Create a goal. The goal member is dishwasher_id, assign it a value of 1, and then sendGoal sends the goal to the server. It includes goal and three callback functions, namely doneCb, activeCb and feedbackCb.

xxxxxxxxxx
// When the action is completed, the callback function will be called once
void doneCb(const actionlib::SimpleClientGoalState& state,
        const learn_action::DoDishesResultConstPtr& result)
{
    ROS_INFO("Yay! The dishes are now clean");
    ros::shutdown();
}

// When the action is activated, the callback function will be called once.
void activeCb()
{
    ROS_INFO("Goal just went active");
}

// callback function called after receiving feedback
void feedbackCb(const learn_action::DoDishesFeedbackConstPtr& feedback)
{
    ROS_INFO(" percent_complete : %f ", feedback->percent_complete);
}

Here is the feedback member percen_complete. We can use rosmsg info to query the specific members and enter it in the terminal.

xxxxxxxxxx
rosmsg info learn_action/DoDishesFeedback

image-20231026152330110

The same applies to the goal above. Enter in the terminal.

xxxxxxxxxx
rosmsg info learn_action/DoDishesGoal

image-20231026152502874

Summary: First create a client to call the service, then wait for the service to start. After the service starts, define a goal, and then send the goal to the server. Please refer to the official documentation for the parameter API interface:

actionlib: actionlib::SimpleActionClient< ActionSpec > Class Template Reference (ros.org)

 

ROS service server
ROS action server

COMPANY

  • About us
  • Team Style
  • Blog

LEARNING & EXPLORATION

  • Tutorials
  • Edge AI hardware
  • Educational robots
  • Embedded intelligent hardware

WHERE TO BUY

  • Yahboom Online Store
  • Amazon
  • Alibaba
  • AliExpress
  • Mercado

TECHNOLOGY SUPPORT

  • Email: support@yahboom.com

BE A DISTRIBUTOR

  • Email: sales@yahboom.com
QR Code

Copyright © 2017-2026 Yahboom. All Rights Reserved.

EN/中文