mi-task/test/cy-mark/src/marker_service.cpp
havoc420ubuntu 30d02cba9d finish mark;
test(cy-mark): improve marker placement service and update test case

- Update marker_client.py to test with different coordinates and color
- Remove model_marker.sdf file as it's no longer needed
- Enhance marker_service.cpp with better error handling and logging
2025-05-14 17:15:49 +00:00

134 lines
4.7 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "cyberdog_marker/marker_service.hpp"
namespace cyberdog
{
namespace marker
{
MarkerService::MarkerService(const rclcpp::NodeOptions & options)
: Node("cyberdog_marker_service", options),
marker_count_(0)
{
// 创建服务提供位置标记功能
place_marker_service_ = create_service<cyberdog_marker::srv::PlaceMarker>(
"place_marker",
std::bind(
&MarkerService::handle_place_marker, this,
std::placeholders::_1, std::placeholders::_2));
// 创建客户端连接到Gazebo的spawn_entity服务
spawn_entity_client_ = create_client<gazebo_msgs::srv::SpawnEntity>("spawn_entity");
RCLCPP_INFO(get_logger(), "Marker service started");
}
void MarkerService::handle_place_marker(
const std::shared_ptr<cyberdog_marker::srv::PlaceMarker::Request> request,
std::shared_ptr<cyberdog_marker::srv::PlaceMarker::Response> response)
{
// 等待Gazebo服务可用
if (!spawn_entity_client_->wait_for_service(std::chrono::seconds(1))) { // 缩短超时,快速失败
response->success = false;
response->message = "Gazebo spawn_entity service not available";
RCLCPP_ERROR(get_logger(), "%s", response->message.c_str());
return;
}
// 生成唯一的标记名称
marker_count_++;
std::string marker_name = "marker_" + std::to_string(marker_count_);
// 生成SDF标记内容
std::string marker_sdf = generate_marker_sdf(request->color);
// 创建spawn_entity请求
auto spawn_request = std::make_shared<gazebo_msgs::srv::SpawnEntity::Request>();
spawn_request->name = marker_name;
spawn_request->xml = marker_sdf;
spawn_request->robot_namespace = ""; // 通常为空除非你的Gazebo模型在特定命名空间下
// 设置标记位置
spawn_request->initial_pose.position.x = request->x;
spawn_request->initial_pose.position.y = request->y;
spawn_request->initial_pose.position.z = request->z;
spawn_request->initial_pose.orientation.w = 1.0; // 默认无旋转
// 发送请求
auto future_response = spawn_entity_client_->async_send_request(spawn_request);
// 让我们先尝试一个简单的阻塞获取看看gazebo服务是否足够快
std::chrono::seconds timeout(5); // 设置一个超时
auto future_status = future_response.wait_for(timeout);
if (future_status == std::future_status::ready) {
auto spawn_response_ptr = future_response.get();
response->success = spawn_response_ptr->success;
if (response->success) {
response->message = "Successfully placed marker '" + marker_name + "' at ("
+ std::to_string(request->x) + ", "
+ std::to_string(request->y) + ", "
+ std::to_string(request->z) + ")";
} else {
response->message = "Failed to place marker: " + spawn_response_ptr->status_message;
}
} else if (future_status == std::future_status::timeout) {
response->success = false;
response->message = "Gazebo spawn_entity service call timed out";
} else { // deferred
response->success = false;
response->message = "Gazebo spawn_entity service call deferred or error";
}
if (response->success) {
RCLCPP_INFO(get_logger(), "%s", response->message.c_str());
} else {
RCLCPP_ERROR(get_logger(), "%s", response->message.c_str());
}
}
std::string MarkerService::generate_marker_sdf(const std::string & color, double radius)
{
// 解析颜色
double r = 1.0, g = 0.0, b = 0.0; // 默认红色
if (color == "red") {
r = 1.0; g = 0.0; b = 0.0;
} else if (color == "green") {
r = 0.0; g = 1.0; b = 0.0;
} else if (color == "blue") {
r = 0.0; g = 0.0; b = 1.0;
} else if (color == "yellow") {
r = 1.0; g = 1.0; b = 0.0;
}
// 创建SDF模型
std::stringstream sdf;
sdf << "<?xml version='1.0'?>\n"
<< "<sdf version='1.6'>\n"
<< " <model name='marker'>\n"
<< " <static>true</static>\n"
<< " <link name='link'>\n"
<< " <visual name='visual'>\n"
<< " <cast_shadows>false</cast_shadows>\n"
<< " <geometry>\n"
<< " <sphere>\n"
<< " <radius>" << radius << "</radius>\n"
<< " </sphere>\n"
<< " </geometry>\n"
<< " <material>\n"
<< " <ambient>" << r << " " << g << " " << b << " 1</ambient>\n"
<< " <diffuse>" << r << " " << g << " " << b << " 1</diffuse>\n"
<< " <specular>0.1 0.1 0.1 1</specular>\n"
<< " </material>\n"
<< " </visual>\n"
<< " </link>\n"
<< " </model>\n"
<< "</sdf>";
return sdf.str();
}
} // namespace marker
} // namespace cyberdog
#include "rclcpp_components/register_node_macro.hpp"
RCLCPP_COMPONENTS_REGISTER_NODE(cyberdog::marker::MarkerService)