Detour-API:修订间差异
无编辑摘要 |
|||
| 第490行: | 第490行: | ||
"is2D": true, // 在二维平面运动 | "is2D": true, // 在二维平面运动 | ||
"integrated": true, | "integrated": true, | ||
"startingTick": 0, // | "startingTick": 0, // 时间戳,不变表示这是一条航迹,建议程序启动时用系统Ticks为初始值 | ||
"x": 0.0, // 当前位姿 | "x": 0.0, // 当前位姿 | ||
"y": 0.0, | "y": 0.0, | ||
2024年7月1日 (一) 09:45的版本
1. 前言
Detour在4321端口启动Web API服务,为上层应用提供定位、配置和辅助功能。
2. 接口定义
2.1 定位
2.1.1 读取位姿
方法:GET 路径:/getPos 返回:JSON
举例:
GET http://127.0.0.1:4321/getPos
{
"x": 190702.844, // 位置单位是毫米,使用直角坐标系
"y": 336956.9,
"th": 113.340424, // 角度单位是度
"l_step": 27, // 定位步长,=2表示定位正常,=9999表示手动输入位置
// >2表示回环失败,此时机器人位置附近的关键帧配准得分低于阈值,
// 或关键帧计算出的位姿与当前位姿偏差过大而被过滤。l_step值
// 越大表示回环失败时间越长。一般而言,在行驶时,可能存在
// 短暂的激光SLAM定位不良区域,l_step<15可继续行驶,用
// 激光里程计继续输出位姿,此时激光里程计累计误差较小。
// l_step>15时应停车,重新定位成功后继续。
"tick": 63855102200497 // 时间戳,系统时间的Tick
}
// 如果发生错误,比如激光雷达停止发送测量数据,则error属性
// 显示错误。使用位姿接口数据时,应校验error字段,如非null则位姿不可用。
{
"x": 129163.734,
"y": 416628.938,
"th": 138.75148,
"l_step": 200,
"tick": 63855105852361,
"error": "Timeout"
}
说明:
- 使用l_step判断建图质量。建图后遥控移动机器人沿工作路线走一圈,观察l_step值,由于不存在理想的SLAM环境,因此l_step值会短暂>2,一般<7以内可认为SLAM稳定工作。如在固定路段出现回环失败现象,则要考虑应对措施,比如用挡板改善环境轮廓、用反光棒切换到有反SLAM。
- 在运行时,可根据l_step结合运动状态判断“盲目行驶”风险,如l_step>15且在移动,应停车报警,恢复定位后继续行驶。l_step计算涉及多个因素,因此用范围来判断,如给出的<15区间,可根据实际情况调整区间使用。
- 激光SLAM以激光里程计输出位姿(x, y, theta)。激光里程计根据相邻激光雷达帧点云计算位移(距离和角度),积分以推算移动机器人航迹,激光里程计持续输出位姿。回环线程则搜索移动机器人附近的关键帧(路标),计算激光雷达帧点云与它们的配准程度,锁定配准得分高于阈值且最高的关键帧,以此修正激光里程计的累积误差,这个过程称为回环。l_step=2表示移动机器人当前位姿附近的关键帧被锁定,因而获得精确位置。l_step>2则表示回环失败,激光里程计继续输出位姿,但是关键帧锁定失败,因此累积误差不能消除,其值越大,输出位姿的误差性可能越大。l_step<15是我们给出的经验区间。
2.1.2 暂停定位
方法:GET 路径:/pause 返回:JSON
举例:
GET http://127.0.0.1:4321/pause
{
"success": true,
"id": 0
}
说明:
- 与“恢复定位”接口配套使用。在Detour发布“紧耦合”特性之前,此接口用于暂停Detour定位功能(包括激光里程计和回环功能),改用目标跟随、巡线或轮里程计等其他定位手段行驶,通过特定场景后恢复定位,并用“指定位置重定位”功能重定位,以恢复激光SLAM功能。
- 暂停定位接口相当于关闭Detour,使其不再输出位姿,此时“读取位姿”接口将返回"timeout"错误。
2.1.3 恢复定位
方法:GET 路径:/resume 返回:JSON
举例:
GET http://127.0.0.1:4321/resume
{
"success": true,
"id": 0
}
2.1.4 全局重定位
方法:GET 路径:/relocalize 返回:JSON
举例:
GET http://127.0.0.1:4321/relocalize
{
"performed": true // 执行成功
}
说明:
- 全局重定位指令Detour搜索所有关键帧,取与当前点云配准分数最高者锁定,获得移动机器人当前位姿。如果点云与关键帧配准分数均低于阈值,则重定位失败。
- 全局重定位应用在环境轮廓稳定且有独特几何特征区域。如果环境轮廓与数个关键帧相似,且得分相差无几,则会定位到错误位置。建议在固定位置使用重定位接口,比如在干道旁设置固定的重定位站点。
2.1.5 指定位置重定位
方法:GET 路径:/relocalize 返回:JSON
举例:
// 以(x, y, th)设定移动机器人当前位姿,注意它们都是float类型,值都应有小数点后1位。
// 激光里程计的航迹切到给定位姿。
// 如果给定位姿与实际位姿的距离过大,将导致回环失败(可锁定关键帧给出的观测位姿与当前位姿差
// 大于误差范围时,关键帧将被丢弃,见detour参数说明)。
GET http://127.0.0.1:4321/setLocation?x=100.0&y=100.0&th=90.0
{
"x": 102.061165,
"y": 97.67917,
"th": 90.0271454,
"l_step": 10000,
"tick": 63855111242596
}
说明:
- 一般用于SLAM不良区域。比如潜伏式牵引车使用目标跟踪功能从料车缓存机构走出时(料车腿和缓存机构遮挡雷达视野而导致定位错误),指定位置使激光SLAM重新定位。
2.1.6 指定关键帧回环
方法:GET 路径:/relocalize 返回:JSON
举例:
// 指示激光SLAM优先选用给定的关键帧。
// preferredKfId赋值为逗号分隔的关键帧Id集合。
// 给定的关键帧被列入优先选用集合,提高其匹配权重。
GET http://127.0.0.1:4321/setPreferredKFID?preferredKfiId=1130788673,1815389948
{
"success": true
}
说明:
- 如果同一个站点的停准精度差异是锁定不同关键帧所致,可使用此接口指示激光SLAM选用特定的关键帧,以提高SLAM精度稳定性。在有限视野场景下(如180度激光雷达视野,或周围环境轮廓不良),可能会锁定不同关键帧(如站点前关键帧由于点云配准分数较低而未选用)而带来厘米级定位误差。此接口用于提高特定关键帧权重,以稳定锁定该关键帧,获得稳定的位姿。
2.1.7 启停回环功能
方法:GET 路径:/switchPosMatch 返回:JSON
举例:
// 启用(或停用)给定图层的回环功能。
// disable=true表示启用,false表示停用。
// name是图层名称(单线激光SLAM标签的Lidar点云图层)
GET http://127.0.0.1:4321/switchPosMatch?disabled=false&name=mainmap
{
"performed": true
}
说明:
- 停用给定图层的回环功能时,激光SLAM不再搜索该图层的关键帧。
- 本接口与暂停定位接口的差异在于,前者只是停用指定图层回环功能,激光里程计继续输出位姿;后者停止激光里程计和回环,输出位姿不可使用。
2.2 配置
2.2.1 加载地图
方法:GET 路径:/loadMap 返回:JSON
举例:
// 指定图层加载激光地图。
// name是图层名称,fn是激光地图文件名称。
GET http://127.0.0.1:4321/loadMap?name=mainmap&fn=mainmap.2dlm
{
"performed": true,
"success": false
}
说明:
- 可用于激光地图切换场景。比如移动机器人乘坐电梯到二楼时,把激光地图从一楼切换到二楼。
2.2.2 保存地图
方法:GET 路径:/saveMap 返回:JSON
举例:
GET http://127.0.0.1:4321/saveMap?name=mainmap&fn=mainmap.2dlm
{
"performed": true
}
说明:
- 图层的激光地图修改后,使用本接口将其存入激光地图文件。
2.2.3 读取配置文件
方法:GET 路径:/getConf 返回:JSON
举例:
GET http://127.0.0.1:4321/getConf
{
"overrideLanguage": "/",
"license": "",
"initX": 15659.2,
"initY": 2436.9,
"initTh": 11.7,
"recordLastPos": true,
"layout": {
"chassis": {
"width": 1200.0,
"length": 2000.0,
"contour": [
-445.0,
330.0,
445.0,
330.0,
445.0,
-330.0,
-445.0,
-330.0
]
},
"components": [
]
},
"odometries": [
],
"positioning": [
],
"autoStart": true,
"debug": true,
"useGPU": true,
"TCtimeWndSz": 150,
"TCtimeWndLimit": 700,
"useTC": true,
"guru": {
"SpatialIndex2StageCache": 4194304,
"SpatialIndex1StageCache": 1048576,
"ICPFastIterFac": 0.8,
"ICPUseFastMode": false,
"ICP2DMaxIter": 16,
"RippleEnableEqualize": true,
"Lidar2dMapMaxIter": 50,
"phaseLockLvl": 3,
"rotMapProjectionLength": 500.0,
"gicp_p2pfac": 0.02,
"extractPlaneThresE": 700.0,
"lo3dlineWeightScale": 0.3,
"inputScale": 1.0,
"Lidar2DRippleDistDecay": 15000.0,
"Lidar2DRippleScale": 1.0,
"SI2DRectSmall": 130,
"SI2DRectBig": 600,
"TCVarMax": 1600.0,
"TCMaxBadEdges": 3,
"TCKalmanUseCurrentFac": 0.2,
"debugReg2D": true,
"ICP2ddebugSource": -1,
"ICP2dReflexWeightTranslateFac": 3.0,
"TCInterconnectType": 0,
"TCAutoCaliberation": false,
"dumpCriticalData": false,
"dumpLocation": false,
"logKeepDays": 7,
"GOAllowSO3": false,
"TCAllowSO3": true,
"MaxTCIters": 1000,
"GOStopMvmt": 1.0,
"TCDiscardFactor": 0.4,
"TCCouplingSigmaVXY": 0.2,
"TCCouplingSigmaVTh": 0.5
},
"recordPosInterval": 500,
"minimized": false
}
说明:
- 本接口返回Detour使用的配置文件内容,一般是detour.json。
- 可结合本接口和组件属性赋值接口实现激光雷达自动标定功能。首先读出配置,解析出要标定的激光雷达外参值(x, y, th),根据激光雷达外参标定方法实现移动机器人的标定行走功能,使用读取位姿、启停回环功能、组件属性赋值等接口计算并设置外参。
2.2.4 组件属性赋值
方法:GET 路径:/set 返回:JSON
举例:
// 可设置以下组件的属性值:
// - 车体部件。车体布局编辑器中列出的车体部件,一般是激光雷达,比如frontlidar。
// - 里程计。里程计标签中的里程计。
// - 地图。单线激光SLAM标签中的Lidar点云图层,比如mainmap。
// path是对象属性,本例是frontlidar.x,即激光雷达的x外参。
// val是值。
GET http://127.0.0.1:4321/set?path=frontlidar.x&val=500
{
"success": true
}
说明:
- Detour使用该接口配置DetourLite参数。由于组件属性赋值不支持创建组件,因此在Detour创建激光雷达时,该雷达不会同步给DetourLite,进而触发对该雷达属性赋值时报“DetourLite参数设置错误”提示。
2.2.5 上传资源
方法:POST 路径:/uploadRes 返回:JSON
举例:
// fn是资源文件名。
// POST Body是上传的资源文件内容。
POST http://127.0.0.1:4321/uploadRes?fn=foo
{
"performed": true
}
说明:
- 本接口可向Detour所在目录上传文件。比如激光地图文件。
2.2.6 下载资源
方法:GET 路径:/downloadRes 返回:字节流
举例:
GET http://127.0.0.1:4321/downloadRes?fn=foo
// 返回foo文件内容的字节流
2.3 状态
2.3.1 读取运行统计
方法:GET 路径:/getStat 返回:JSON
举例:
GET http://127.0.0.1:4321/getStat
{
"runningSeconds": 878.7448942,
"layoutStat": {
"frontlidar": {
"status": "等待帧",
"lidar_tick": 2542,
"interval": 77,
"validPoints": 196,
"preprocessTime": 0.0,
"timeBudget": 81.036527022839024,
"reflexN": 0.0,
"selfFitting": 0.0
},
"cart_odometry": {
"status": "初始化捕捉完毕",
"use": true,
"feedstate": "未开始捕获",
"time": 0,
"type": "/",
"counter": 0,
"pos": "/",
"selfFitting": 0.0
}
},
"odoStat": {
"odometry_0": {
"reg_ms": 6.0,
"loop_ms": 136.0,
"interval": 1,
"reg_mode": 0,
"kf_state": "10011/+1",
"SeqScore": 0.950587451,
"LOScore": 0.9299651,
"kfreason": ".",
"otherDebug": "",
"status": "waitframe",
"pause": false
}
},
"posStat": {},
"TCStat": {
"commitId": 1394,
"computeStat": "tcfrontlidar...tp",
"fitmethod": 1,
"goIters": 0,
"discarding": "",
"fitexplain": "frontlidar:5L/1.61",
"poseEstim": "/",
"TCPerf": "rigid:0.054,go:0.0622,post:0.0188",
"CouplingScores": "frontlidar(5):1.00/1.00",
"TCVar": 0.0,
"err": 0.0,
"historyLs": "frontlidar:N1/5",
"powers": "True:(,()"
},
"GOStat": {
"maxTension": 0.0,
"edgeN": 0,
"OPS": 8,
"Use": true
},
"licence": "DID:4D222EB2BEE27897",
"globalStat": {
"paused": false,
"IsSettingPosition": false
}
}
说明:
- 返回结果与Detour上相应对象的状态一致。
2.3.2 导出工作区
方法:GET 路径:/dumpWorkspace 返回:JSON
举例:
GET http://127.0.0.1:4321/dumpWorkspace
OK
说明:
- 在Detour的log/workspace目录下生成图像日志,包括一张PNG图片,内容为Detour主界面的地图;一个运行日志文件。
2.3.3 读取点云
方法:GET 路径:/getSensors 返回:字节流
举例:
GET http://127.0.0.1:4321/getSensors
// 返回字节流是点云数据,伪代码表述格式如下:
[
{ // 激光雷达
lidar.name : String; // 雷达名称,C# String类型
keyFrame.x : float; // 关键帧位姿
keyFrame.y : float;
keyFrame.th : float;
pointCloud.length : int; // 点云数组长度
[
point.x : float; // 测量点坐标
point.y : float;
]
}
]
说明:
- Detour使用此接口读取DetourLite点云数据。
- 调用该接口的频率应控制在2Hz以内,以免干扰Detour内核计算性能。
- 非必要不使用原则。如,在丢定位时(如l_step>15),在管控的维护功能界面显示点云,以帮助操作者识别移动机器人实际位姿,然后使用指定位置重定位接口找回定位。在这个场景中,只需在处理定位问题时读取点云,处理完毕后停止调用接口。
2.3.4 读取版本
方法:GET 路径:/getVersion 返回:JSON
举例:
GET http://127.0.0.1:4321/getVersion
shicong-liu@2024-06-26T13:25:22+08|master_b8dc
2.4 操作
2.4.1 调用方法
方法:GET 路径:/call 返回:JSON
举例:
// 调用对象方法。
// cmd是对象方法。本例是调用cart_odometry.capture()方法,即
// 触发外部定位源cart_odometry(轮里程计)的捕获方法。
GET http://127.0.0.1:4321/call?cmd=cart_odometry.capture()
// 返回该方法的返回值
{
"result": "void"
}
说明:
- 本接口相当于RPC(Remote Procedure Call)调用。应根据代码调用。
2.4.2 设置激光雷达蒙板
方法:POST 路径:/setLidar2DOdometryMask 返回:JSON
举例:
// odometry是里程计标签中的里程计名称。本例的odometry_0是默认激光里程计名称。
// POST Body是蒙板顶点数组,用于构造出封闭多边形,落在多边形内的点云都会被过滤。
POST http://127.0.0.1:4321/setLidar2DOdometryMask?odometry=odometry_0
[
{
"X": 123,
"Y": 456
},
{
"X": 123,
"Y": 456
},
{
"X": 123,
"Y": 456
}
]
{
"success": true
}
说明:
- 本接口只影响内存中的配置,不会存入配置文件。
- 坐标参考车体编辑器,直角坐标系的原点在底盘几何中心。
2.4 定位
2.4.1 外部定位源
方法:POST 路径:/postExternPosition 返回:JSON
举例:
// name是外部定位源。本例的cart_odometry是IMU轮里程计。
// POST Body是外部定位源的航迹。
POST http://127.0.0.1:4321/postExternPosition?name=cart_odometry
{
"name": "wheel", // 轮里程计
"counter": 0, // 单调+1
"hasTranslation": true, // 可移动
"hasRotation": true, // 可旋转
"is3D": false,
"is2D": true, // 在二维平面运动
"integrated": true,
"startingTick": 0, // 时间戳,不变表示这是一条航迹,建议程序启动时用系统Ticks为初始值
"x": 0.0, // 当前位姿
"y": 0.0,
"z": 0.0, // 二维平面的z总是0
"th": 0.0,
}
{
"performed": true
}
说明:
- 向Detour推送外部定位源的位姿。外部定位源一般是IMU轮里程计、GNSS RTK。Detour紧耦合功能融合多个里程计,择优输出一个位姿。
- IMU轮里程计的位姿发布频率建议20Hz(经测试获得的经验值)。
- 外部定位源的inputType="web",默认是"internal"(表示从Medulla发布)。设置错误将导致接口调用失败。
- 集成外部定位源时,应测试其发布频率,以免过快或过慢频率干扰紧耦合错误选用里程计。