Detour-API:修订间差异

来自MDCS wiki
跳到导航 跳到搜索
 
(未显示2个用户的3个中间版本)
第322行: 第322行:
Get http://127.0.0.1:4321/set?path=frontlidar.name&val=frontlidar
Get http://127.0.0.1:4321/set?path=frontlidar.name&val=frontlidar


{
    "performed": true
}
</syntaxhighlight>
=== 2.2.8 外部加载二维码地图 ===
'''方法''':Get'''路径''':/call?cmd=tagmap.load()'''返回''':JSON
举例:<syntaxhighlight lang="js">
// load 里面输入二维码地图路径即可
Get 127.0.0.1:4321/call?cmd=tagmap.load(d:/src/detour/build/fuck.json)
re
{
{
     "performed": true
     "performed": true
第504行: 第518行:


=== 2.4.1 外部定位源 ===
=== 2.4.1 外部定位源 ===
输入外部定位源前,首先要在车体编辑器里增加对应的“外部定位源”部件
'''方法''':POST '''路径''':/postExternPosition '''返回''':JSON
'''方法''':POST '''路径''':/postExternPosition '''返回''':JSON


第511行: 第527行:
POST http://127.0.0.1:4321/postExternPosition?name=cart_odometry
POST http://127.0.0.1:4321/postExternPosition?name=cart_odometry
{
{
   "name": "wheel", // 轮里程计
   "name": "cart_odometry", // 轮里程计+IMU对应在Detour中的部件名
   "counter": 0, // 单调+1
   "counter": 0, // 单调+1
   "hasTranslation": true, // 可移动,(x, y)  
   "hasTranslation": true, // 可移动,(x, y)  
第535行: 第551行:
* 外部定位源的inputType="web",默认是"internal"(表示从Medulla发布)。设置错误将导致接口调用失败。
* 外部定位源的inputType="web",默认是"internal"(表示从Medulla发布)。设置错误将导致接口调用失败。
* 集成外部定位源时,应测试其发布频率,以免过快或过慢频率干扰紧耦合错误选用里程计。
* 集成外部定位源时,应测试其发布频率,以免过快或过慢频率干扰紧耦合错误选用里程计。
* 以下是外部定位源表:
{| class="wikitable"
|+定位源类型和设置方法
!
!hasTranslation
!hasRotation
!is3D
!is2D
!integrated
!toRemap
|-
|GNSS定位
|true
|true
如果有的话
|false
|true
|false
|true
经纬度-地图位置需要标定:[[使用手册 - 卫星或基站定位标定|使用手册]]
|-
|轮编里程计(须自行融合IMU)
|true
|true
|false
|true
|true
须自行积分,直接从0开始积分即可
|
|}


2.4.2 外部二维码输入
=== 2.4.2 外部二维码输入 ===
 
'''方法''':Get'''路径''':/call?cmd=lesstag.inputextern(id,x,y,th) '''返回''':JSON
'''方法''':Get'''路径''':/call?cmd=lesstag.inputextern(id,x,y,th) '''返回''':JSON



2025年4月28日 (一) 16:34的最新版本


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 路径:/setLocation 返回: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=false表示启用,true表示停用。
// name是图层名称(单线激光SLAM标签的Lidar点云图层)
GET http://127.0.0.1:4321/switchPosMatch?disabled=false&name=mainmap

{
    "performed": true
}

说明:

  • 停用给定图层的回环功能时,激光SLAM不再搜索该图层的关键帧。
  • 本接口与暂停定位接口的差异在于,前者只是停用指定图层回环功能,激光里程计继续输出位姿;后者停止激光里程计和回环,输出位姿不可使用。

2.1.8 开启建图/锁定图层

  • 方法:GET 路径:/call?cmd=ground.SwitchMode(1) 返回:{"result":"void"} 举例:
    // 开启或关闭建图
    // 一般ground表示地纹图层名称,mainmap是激光图层名称
    // 0是建图  1锁定图层
    GET http:/call?cmd=ground.SwitchMode(1)
    return
    {
        "result":"void"
        
    }
    
    说明:
    • 注意图层名称,开启建图和锁定UI界面的状态并不会变化。

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
}

说明:

  • 图层的激光地图修改后,使用本接口将其存入激光地图文件。

2dlm地图格式可以参考该C#代码:2dlm地图文件格式 (lessokaji.com)

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.2.7 保存导航配置

方法:Get路径:/set 返回:JSON

举例:

// 
// 比如保存雷达名称,就可以保存所有配置信息到本地了
Get http://127.0.0.1:4321/set?path=frontlidar.name&val=frontlidar

{
    "performed": true
}


2.2.8 外部加载二维码地图

方法:Get路径:/call?cmd=tagmap.load()返回:JSON

举例:

// load 里面输入二维码地图路径即可
Get 127.0.0.1:4321/call?cmd=tagmap.load(d:/src/detour/build/fuck.json)

re
{
    "performed": true
}

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": "cart_odometry",	// 轮里程计+IMU对应在Detour中的部件名
  "counter": 0,				// 单调+1
  "hasTranslation": true,	 // 可移动,(x, y) 
  "hasRotation": true,		// 可旋转,(th)
  "is3D": false,			// 在三维平面运动,输出(x, y, z, th)
  "is2D": true,				// 在二维平面运动,输出(x, y, th)
  "integrated": true,	// 是否通过积分得到的位姿(轮里程计通过积分获得,gps是绝对位置)
  "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发布)。设置错误将导致接口调用失败。
  • 集成外部定位源时,应测试其发布频率,以免过快或过慢频率干扰紧耦合错误选用里程计。
  • 以下是外部定位源表:
定位源类型和设置方法
hasTranslation hasRotation is3D is2D integrated toRemap
GNSS定位 true true

如果有的话

false true false true

经纬度-地图位置需要标定:使用手册

轮编里程计(须自行融合IMU) true true false true true

须自行积分,直接从0开始积分即可

2.4.2 外部二维码输入

方法:Get路径:/call?cmd=lesstag.inputextern(id,x,y,th) 返回:JSON

举例:

// id,x,y,th分别表示二维码的tag,xyth数值。
Get http://127.0.0.1:4321/call?cmd=lesstag.inputextern(id,x,y,th)
{
    "result": true
}

说明:

  • 配置此项功能需要把D参数中二维码配置useExtern改成true才可以生效