编写接口.srv文件:
cd ros2_ws/src
ros2 pkg create service_interfaces --build-type ament_cmake
cd service_interfaces
mkdir srv
touch srv/Ball.srv
touch srv/Disk.srv
编辑Ball.srv
uint32 ball_mass
uint32 ball_radius
—
uint32 ball_inertia
编辑Disk.srv
uint32 disk_mass
uint32 disk_radius
—
uint32 disk_inertia
修改CMakeLists.txt
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
“srv/Ball.srv”
“srv/Disk.srv”
DEPENDENCIES
)
修改package.xml
<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
生成接口
colcon build --packages-select service_interfaces
服务程序实现
新建工作空间
mkdir -p ros2_ws/src
cd ros2_ws/src
新建 功能包
ros2 pkg create ball_and_disk --build-type ament_cmake --dependencies rclcpp service_interfaces
cd ball_and_disk/src
touch service_ball.cpp
touch service_disk.cpp
touch client.cpp
编写Disk服务端节点
#include “rclcpp/rclcpp.hpp”
#include “service_interfaces/srv/disk.hpp”
using std::placeholders::_1;
using std::placeholders::_2;
//创建一个类节点
class DiskInertia : public rclcpp::Node
{
public:
DiskInertia() : Node(“DiskInertia”)
{
RCLCPP_INFO(this->get_logger(), “计算薄盘的转动惯量:I = (2/3) * m * r^2.”);
// 实例化回调组, 作用为避免死锁
callback = this->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
// 实例化服务
Server = this->create_service<service_interfaces::srv::Calculate>(“Calculate”,
std::bind(&DiskInertia::calc_callback,this,_1,_2),
rmw_qos_profile_services_default,
callback);
}
private:
// 声明一个服务回调组
rclcpp::CallbackGroup::SharedPtr callback;
// 声明一个服务端
rclcpp::Service<service_interfaces::srv::Calculate>::SharedPtr Server;
// 声明一个回调函数
void calc_callback(const service_interfaces::srv::Calculate::Request::SharedPtr request,
const service_interfaces::srv::Calculate::Response::SharedPtr response)
{
if(request->ball_mass > 0 && request->ball_radius > 0) {
RCLCPP_INFO(this->get_logger(), “薄盘的质量为:”, request->ball_mass.c_str(), “薄盘的半径为:”, request->ball_radius.c_str());
unsigned int Inertia = 2 / 3 * request->ball_mass * request->ball_radius * request->ball_radius;
RCLCPP_INFO(this->get_logger(), “薄盘的转动惯量为:”, Inertia);
response->moment_inertia = Inertia;
} else {
RCLCPP_INFO(this->get_logger(), "非法请求:质量和半径需大于0: ", Inertia);
response->moment_inertia = 0;
}
}
};
int main(int argc, char **argv)
{
rclcpp::init(argc, argv);
auto node = std::make_shared();
// 把节点的执行器变成多线程执行器, 避免死锁
rclcpp::executors::MultiThreadedExecutor exector;
exector.add_node(node);
exector.spin();
rclcpp::shutdown();
return 0;
}