highlevel_skills 模块
daystar_api.highlevel_skills 是基于 lowlevel 接口封装的高层任务技能集合。
相比 lowlevel 接口直接对应单个 ROS 服务/动作,highlevel skill 通常组合多个 lowlevel 调用、
内置前置状态检查与降级逻辑,对调用方屏蔽底层状态机复杂性。
模块概览
当前已收录的 highlevel skill:
导航类::py:func:`go_to_location`(导航到指定点位 / 位姿 / 经过多点)
快速示例
from daystar_api.highlevel_skills import go_to_location
# 1. 单点(自动路网规划)
result = go_to_location("茶水间")
print(f"导航结果: {result.state.cn}")
# 2. 多点路线(直接执行,跳过路网;最后一个即终点)
result = go_to_location(locations=["大厅", "走廊", "会议室"])
# 3. 带回调
def on_complete(ev): print("到达", ev)
result = go_to_location("充电桩", complete_callback=on_complete)
Note
highlevel skill 是纯 Python 实现(位于 daystar_api/highlevel_skills/ 包下)。
本页采用手写 py:function 指令而非 autodoc,与同类无法 autodoc 的页面
(逻辑流控制)风格对齐——daystar_api 顶层包的导入链涉及 ROS workspace
外部依赖(path_planer_api、_lowlevel_skills 的 pybind 绑定等),
sphinx 构建环境不保证全部可用。
导航类
- go_to_location(location=None, pose=None, locations=None, poses=None, travel_params=None, timeout=600, complete_callback=None, failed_callback=None, progress_callback=None, graph_file=None, start_location=None)
导航到指定命名点位、坐标位姿,或顺序经过多个点位 / 位姿。在执行导航前自动完成定位检查、 姿态调节、控制模式切换等前置步骤;对单点目标支持基于路网文件的最短路径展开。
底层始终走多点导航 API:单点情形本质上等价于”长度为 1 的多点导航”, 因此不再单独调用
_lowlevel_skills.navigation_to_pose()。名字目标(
location/locations)→_lowlevel_skills.navigation_via_locations()位姿目标(
pose/poses) →_lowlevel_skills.navigation_via_poses()
参数互斥规则:
location/pose/locations/poses必须且只能提供其中一个。- Parameters:
location (str | None) – 单个目标点位名称,须已在系统中注册(可通过
_lowlevel_skills.get_available_location()查询)。pose (Pose | None) – 单个目标坐标位姿,通常配合
_lowlevel_skills.get_current_pose()使用以实现”返回原位”。locations (list[str] | None) – 多个已注册点位的顺序列表,最后一个即终点。 想要”先经过 A、B 再到 C”,直接写
locations=["A", "B", "C"]。 提供时跳过路网规划,graph_file/start_location被忽略。poses (list[Pose] | None) – 多个位姿的顺序列表,最后一个即终点。 提供时跳过路网规划,
graph_file/start_location被忽略。travel_params (MsgTravelParams | None) – 导航行驶参数。仅作用于序列最后一个点 (即真正的终点);底层 action server 设计如此。为
None时使用默认值。timeout (int) – 整个导航过程的超时时间(秒),默认
600。上限 30 分钟。complete_callback (callable | None) – 导航成功完成时的回调, 接收
_lowlevel_skills.NavCompleteEvent。failed_callback (callable | None) – 导航失败时的回调, 接收
_lowlevel_skills.NavFailedEvent。progress_callback (callable | None) – 导航进度回调, 接收
_lowlevel_skills.NavProgressEvent。graph_file (str | None) – 路网图文件名或路径。为
None时自动发现GRAPH_DIR中的默认路网(default.yaml优先)。 仅对 ``location`` / ``pose`` 单点目标生效。start_location (str | None) – 起始路网节点名称。为
None时根据当前位置 自动匹配最近节点。仅对 ``location`` / ``pose`` 单点目标生效。
- Returns:
底层多点导航结果。
state.code == 0表示成功;state.cn包含中文描述。- Return type:
- Raises:
GoToLocationError – 前置检查失败或参数不合法时抛出 (如多个目标参数同时提供、目标点位未注册等)。
RuntimeError – 在导航回调内部递归调用本函数(或任何 block=True 的底层 nav API)时由 C++ 层立即抛出,防止 ROS 动作客户端死锁。详见下方”回调死锁防御”。
执行路径:
入参
行为
locations显式列表跳过路网规划,原样作为
navigation_via_locations入参poses显式列表跳过路网规划,原样包装为 PoseStamped 列表后调
navigation_via_poses单
location+ 有可用路网 + 目标在路网中路网最短路径展开为完整节点序列(含起点),一次性调用
navigation_via_locations单
location无路网(或目标不在路网中)退化为单点列表
[location]调navigation_via_locations单
pose+ 有可用路网路网节点 yaml 读 Pose 拼成前缀 + 最终 pose,一次性调用
navigation_via_poses单
pose无路网退化为单点列表
[pose]调navigation_via_posesNote
路网展开后的列表**包含起点节点**(机器人当前位置最近的路网节点),原样下发。 是否 skip 已到达的 waypoint 由底层 navigation 控制器自行判定, Python 高层不做猜测式剔除。这保证了”路网展开”与”显式
locations列表” 在底层眼中完全等价。回调安装机制:
每次调用通过底层 C++ 绑定的
NavCallbackGuardRAII 临时安装 callback, 调用结束自动还原调用前的全局回调(per-call scoped)。不会污染其它模块注册的全局回调。回调死锁防御:
底层
navigation_client_绑定在send_goal_cb_group_``(``MutuallyExclusive), 同组同时只能执行一个回调。若在complete_callback/failed_callback/progress_callback内部又调用 block=True 的 nav API,会等同组下一次回调被派发, 但该组已被当前回调占用——必然死锁。C++ 层加了
thread_local标志 + RAII:进入用户 callback 前置位, 阻塞 nav 入口(RequestNavigationAct(block=true)/WaitForNavigation/RequestCancelNav)检测到立刻抛std::runtime_error,pybind11 自动转 PythonRuntimeError。回调中可安全调用:
block=False的异步派发,get_current_pose/get_robot_state等其它回调组的服务,纯 Python 计算 / 置标志位,threading.Thread起独立线程后在其中调阻塞 nav(独立 OS 线程不触发防御)。回调中禁止调用:
go_to_location(block 隐含 True)/navigation_*(block=True)/wait_for_navigation/cancel_navigation。from daystar_api.highlevel_skills import go_to_location from daystar_api.lowlevel_skills import get_current_pose, Pose # 1. 单点(自动路网规划,无路网则直接导航) result = go_to_location("茶水间") if result.state.code != 0: raise RuntimeError(f"导航失败: {result.state.cn}") # 2. 多点名字路线(直接执行,不规划。"先去 A 再去 B 最后到 C" 就走这里) result = go_to_location(locations=["大厅", "走廊", "会议室"]) # 3. 多点位姿 result = go_to_location(poses=[pose_a, pose_b, pose_c]) # 4. 返回原位(先记录出发位置,执行任务后回去) pose_resp = get_current_pose() origin_pose = pose_resp.response.location_pose # ... 执行中间任务 ... result = go_to_location(pose=origin_pose) print(f"返回原位: {result.state.cn}") # 5. 带回调(callback 内禁止调阻塞 nav API) def on_complete(ev): print("到达终点", ev) def on_failed(ev): print("失败", ev) result = go_to_location( "充电桩", complete_callback=on_complete, failed_callback=on_failed, ) # 6. 回调中发起下一段导航的推荐做法:主线程串行 result = go_to_location("A") if result.state.code == 0: result = go_to_location("B")
- exception GoToLocationError
go_to_location前置检查失败或参数不合法时抛出。继承自RuntimeError。
相关数据类型
:class:`_lowlevel_skills.NavigationViaPosesResponse`(返回类型)
_lowlevel_skills.NavCompleteEvent/_lowlevel_skills.NavFailedEvent/ :class:`_lowlevel_skills.NavProgressEvent`(回调事件)_lowlevel_skills.Pose`(``pose`/poses参数)_lowlevel_skills.MsgTravelParams`(``travel_params`参数)