跳到主要内容

AddVirtualWall

服务类型: map_manager/srv/AddVirtualWall

服务名: ${MM}/add_virtual_wall

描述

添加虚拟墙到指定楼层。虚拟墙是一条线段,机器人无法穿越。 虚拟墙会被添加到 costmap 中作为致命障碍物。

请求 (Request)

字段类型描述
floor_idstring楼层 ID(如果为空,使用 wall.floor_id)
wallmap_manager/msg/VirtualWall虚拟墙数据(必须包含 id)

响应 (Response)

字段类型描述
successbool操作是否成功
messagestring结果消息或错误信息
wall_idint32添加的虚拟墙 ID

使用示例

命令行调用

Bash
# 添加水平虚拟墙
ros2 service call ${MM}/add_virtual_wall map_manager/srv/AddVirtualWall \
"{floor_id: '1F', wall: {id: 1, start: {x: 0.0, y: 5.0, z: 0.0}, end: {x: 10.0, y: 5.0, z: 0.0}}}"

# 添加垂直虚拟墙
ros2 service call ${MM}/add_virtual_wall map_manager/srv/AddVirtualWall \
"{floor_id: '1F', wall: {id: 2, start: {x: 5.0, y: 0.0, z: 0.0}, end: {x: 5.0, y: 8.0, z: 0.0}}}"

# 添加斜向虚拟墙
ros2 service call ${MM}/add_virtual_wall map_manager/srv/AddVirtualWall \
"{floor_id: '1F', wall: {id: 3, start: {x: 0.0, y: 0.0, z: 0.0}, end: {x: 5.0, y: 5.0, z: 0.0}}}"

Python 示例

Python
from map_manager.srv import AddVirtualWall
from map_manager.msg import VirtualWall
from geometry_msgs.msg import Point
import rclpy
from rclpy.node import Node

class VirtualWallManager(Node):
def __init__(self):
super().__init__('virtual_wall_manager')
self.client = self.create_client(AddVirtualWall, '/add_virtual_wall')
self.client.wait_for_service()
self.next_id = 1

def add_wall(self, floor_id: str, start: tuple, end: tuple, wall_id: int = None):
if wall_id is None:
wall_id = self.next_id
self.next_id += 1

request = AddVirtualWall.Request()
request.floor_id = floor_id
request.wall = VirtualWall(
id=wall_id,
floor_id=floor_id,
start=Point(x=start[0], y=start[1], z=start[2] if len(start) > 2 else 0.0),
end=Point(x=end[0], y=end[1], z=end[2] if len(end) > 2 else 0.0)
)

future = self.client.call_async(request)
rclpy.spin_until_future_complete(self, future)
result = future.result()

if result.success:
print(f"虚拟墙添加成功: ID={result.wall_id}")
else:
print(f"添加失败: {result.message}")
return result

rclpy.init()
manager = VirtualWallManager()

# 添加围栏(4条虚拟墙围成矩形)
manager.add_wall('1F', (0, 0), (10, 0)) # 底边
manager.add_wall('1F', (10, 0), (10, 8)) # 右边
manager.add_wall('1F', (10, 8), (0, 8)) # 顶边
manager.add_wall('1F', (0, 8), (0, 0)) # 左边

rclpy.shutdown()

C++ 示例

C++
#include <rclcpp/rclcpp.hpp>
#include <map_manager/srv/add_virtual_wall.hpp>
#include <map_manager/msg/virtual_wall.hpp>

class VirtualWallManager : public rclcpp::Node {
public:
VirtualWallManager() : Node("virtual_wall_manager"), next_id_(1) {
client_ = create_client<map_manager::srv::AddVirtualWall>(
"/add_virtual_wall");
client_->wait_for_service();
}

bool add_wall(const std::string& floor_id,
double x1, double y1, double x2, double y2,
int wall_id = -1) {
if (wall_id < 0) wall_id = next_id_++;

auto request = std::make_shared<map_manager::srv::AddVirtualWall::Request>();
request->floor_id = floor_id;
request->wall.id = wall_id;
request->wall.floor_id = floor_id;
request->wall.start.x = x1;
request->wall.start.y = y1;
request->wall.start.z = 0;
request->wall.end.x = x2;
request->wall.end.y = y2;
request->wall.end.z = 0;

auto future = client_->async_send_request(request);
if (rclcpp::spin_until_future_complete(shared_from_this(), future) ==
rclcpp::FutureReturnCode::SUCCESS) {
auto result = future.get();
RCLCPP_INFO(get_logger(), "虚拟墙 %s: ID=%d",
result->success ? "添加成功" : "添加失败", result->wall_id);
return result->success;
}
return false;
}

private:
rclcpp::Client<map_manager::srv::AddVirtualWall>::SharedPtr client_;
int next_id_;
};

Costmap 效果

虚拟墙在 costmap 中被标记为致命障碍物:

Text
虚拟墙线段
━━━━━━━━━━━
▓▓▓▓▓▓▓▓▓▓▓ ← 致命障碍物 (254)
░░░░░░░░░░░░░ ← 膨胀区域

相关接口