地图及位置
简介
地图和定位是机器人导航的先决条件,新建地图相当于告知机器人可行走的范围,定位相当于告知机器人目前所处的位置。机器人自带“地图工具“可以完成所有地图和点位的操作,当然你也可以自己使用api完成功能
设点:指告知机器人当前点位的名称,之后可使用接口导航到这个点位
建图及定位
建图及定位可使用系统集成的地图工具进行操作.
地图坐标中,xy是机器人在地图中的位置,theta是机器人的面朝方向(单位为弧度)
定位(设置机器人初始坐标点)
方法名称:setPoseEstimate
调用方式:
try {
JSONObject params = new JSONObject();
//x坐标
params.put(Definition.JSON_NAVI_POSITION_X, x);
//y坐标
params.put(Definition.JSON_NAVI_POSITION_Y, y);
//z坐标
params.put(Definition.JSON_NAVI_POSITION_THETA, theta);
RobotApi.getInstance().setPoseEstimate(reqId, params.toString(), new CommandListener() {
@Override
public void onResult(int result, String message) {
if ("succeed".equals(message)) {
//定位成功
}
}
});
} catch (JSONException e) {
e.printStackTrace();
}
适用平台:
| 豹小秘 | 豹小秘2 | mini | 招财豹 | 招财豹Pro | 豹小秘DP |
| 是 | 是 | 是 | 是 | 是 | 否 |
判断当前是否已定位
方法名称:isRobotEstimate
调用方式:
RobotApi.getInstance().isRobotEstimate(reqId, new CommandListener() {
@Override
public void onResult(int result, String message) {
if (!"true".equals(message)) {
//当前未定位
} else {
//当前已定位
}
}
});
适用平台:
| 豹小秘 | 豹小秘2 | mini | 招财豹 | 招财豹Pro | 豹小秘DP |
| 是 | 是 | 是 | 是 | 是 | 否 |
设置当前位置名称
方法名称:setLocation
调用方式:
RobotApi.getInstance().setLocation(reqId, placeName, new CommandListener() {
@Override
public void onResult(int result, String message) {
if ("succeed".equals(message)) {
//保存位置点成功
} else {
//保存位置点失败
}
}
});
参数
- placeName:位置名称
适用平台:
| 豹小秘 | 豹小秘2 | mini | 招财豹 | 招财豹Pro | 豹小秘DP |
| 是 | 是 | 是 | 是 | 是 | 否 |
注意:调用该接口前需要确保已定位
根据位置名称获取坐标点
方法名称:getLocation 调用方式:
RobotApi.getInstance().getLocation(reqId, placeName, new CommandListener() {
@Override
public void onResult(int result, String message) {
try {
JSONObject json = new JSONObject(message);
//当前位置是否存在
boolean isExist = json.getBoolean(Definition.JSON_NAVI_SITE_EXIST);
if (isExist) {
//x坐标
double x = json.getDouble(Definition.JSON_NAVI_POSITION_X);
//y坐标
double y = json.getDouble(Definition.JSON_NAVI_POSITION_Y);
//面朝方向
double z = json.getDouble(Definition.JSON_NAVI_POSITION_THETA);
}
} catch (JSONException | NullPointerException e) {
e.printStackTrace();
}
}
});
参数:
- placeName:位置名称
适用平台:
| 豹小秘 | 豹小秘2 | mini | 招财豹 | 招财豹Pro | 豹小秘DP |
| 是 | 是 | 是 | 是 | 是 | 否 |
注意:setLocation保存的位置会与地图关联,通过getLocation获取的时候也应该保持相同的地图,否则getLocation获取失败
获取当前地图所有位置点
方法名称:getPlaceList
调用方式:
RobotApi.getInstance().getPlaceList(reqId, new CommandListener() {
@Override
public void onResult(int result, String message) {
try {
JSONArray jsonArray = new JSONArray(message);
int length = jsonArray.length();
for (int i = 0; i < length; i++) {
JSONObject json = jsonArray.getJSONObject(i);
//常用
json.getString("name"); //位置名称
json.getDouble("x"); //x坐标
json.getDouble("y"); //y坐标
//不常用
json.getDouble("theta"); //面朝方向
json.getString("id"); //位置id
json.getLong("time");//更新时间
json.getInt("status"); //0:正常区域,可以到 1:禁行区,不可以到 2:地图外,不可以到
}
} catch (JSONException | NullPointerException e) {
e.printStackTrace();
}
}
});
适用平台:
| 豹小秘 | 豹小秘2 | mini | 招财豹 | 招财豹Pro | 豹小秘DP |
| 是 | 是 | 是 | 是 | 是 | 否 |
获取机器人当前坐标点
方法名称:getPosition
调用方式:
RobotApi.getInstance().getPosition(reqId, new CommandListener() {
@Override
public void onResult(int result, String message) {
try {
JSONObject json = new JSONObject(message);
//x坐标
double x = json.getDouble(Definition.JSON_NAVI_POSITION_X);
//y坐标
double y = json.getDouble(Definition.JSON_NAVI_POSITION_Y);
//面朝方向
double z = json.getDouble(Definition.JSON_NAVI_POSITION_THETA);
} catch (JSONException | NullPointerException e) {
e.printStackTrace();
}
}
});
适用平台:
| 豹小秘 | 豹小秘2 | mini | 招财豹 | 招财豹Pro | 豹小秘DP |
| 是 | 是 | 是 | 是 | 是 | 否 |
注意:调用该接口前需要确保已定位
判断机器人是否在位置点
方法名称:isRobotInLocations 调用方式:
try {
JSONObject params = new JSONObject();
params.put(Definition.JSON_NAVI_TARGET_PLACE_NAME, placeName); //位置名称
params.put(Definition.JSON_NAVI_COORDINATE_DEVIATION, range); //位置范围
RobotApi.getInstance().isRobotInlocations(reqId,
params.toString(), new CommandListener() {
@Override
public void onResult(int result, String message) {
try {
JSONObject json = new JSONObject(message);
//是否在目标点
json.getBoolean(Definition.JSON_NAVI_IS_IN_LOCATION);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
} catch (JSONException e) {
e.printStackTrace();
}
参数
- placeName:位置名称
- range:位置范围,单位m
适用平台:
| 豹小秘 | 豹小秘2 | mini | 招财豹 | 招财豹Pro | 豹小秘DP |
| 是 | 是 | 是 | 是 | 是 | 否 |
获取当前地图名称
方法名称:getMapName 调用方式:
RobotApi.getInstance().getMapName(reqId, new CommandListener() {
@Override
public void onResult(int result, String message) {
if (!TextUtils.isEmpty(message)) {
//message为地图名称
String mapName = message;
}
}
});
适用平台:
| 豹小秘 | 豹小秘2 | mini | 招财豹 | 招财豹Pro | 豹小秘DP |
| 是 | 是 | 是 | 是 | 是 | 否 |
位置状态改变监听
启动一个监听回调,在位置和位置状态发生改变时触发回调。
public class Pose {
public float px, py, theta;
public final long time;
public String name;
/**
* FREE = 0; // 正常区域,可以到
* OBSTACLE = 1; // 禁行区,不可以到
* OUTSIDE = 2; // 地图外,不可以到
*/
public int status;
public float distance;
}
RobotApi.getInstance().registerStatusListener(Definition.STATUS_POSE,
new StatusListener(){
@Override
public void onStatusUpdate(String type, String value) {
Pose pose = GsonUtil.fromJson(value, Pose.class);
}
});
适用平台:
| 豹小秘 | 豹小秘2 | mini | 招财豹 | 招财豹Pro | 豹小秘DP |
| 是 | 是 | 是 | 是 | 是 | 否 |
切换地图
方法名称:switchMap 调用方式:
RobotApi.getInstance().switchMap(reqId, mapName, new CommandListener(){
@Override
public void onResult(int result, String message) {
if ("succeed".equals(message)) {
//切换地图成功
}
}
});
参数
- mapName:地图名称
适用平台:
| 豹小秘 | 豹小秘2 | mini | 招财豹 | 招财豹Pro | 豹小秘DP |
| 是 | 是 | 是 | 是 | 是 | 否 |
注意:切换地图后需要重新定位
读取地图PGM文件并进展示(包含点位坐标转换)
读取地图和坐标转换是一整套地图工具在支撑,示例代码如下:
/*
* getMap
* 获得当前地图
* 地图具有当前机器人位置信息,方向坐标与可点击导航的位置点位
* Get the current map
* The map has current robot position information, direction coordinates and clickable navigation positions
* 共享内存获取 map.pgm 文件
* */
private void getMap(final String name) {
Log.d(TAG, "getMapPgmPFD: mapName=" + name);
//获取 map.pgm 文件描述符
ParcelFileDescriptor mapPgmPFD = ShareMemoryApi.getInstance().getMapPgmPFD(name);
FileDescriptor fd = mapPgmPFD.getFileDescriptor();
FileInputStream fileInputStream = new FileInputStream(fd);
//从文件描述符读取数据流,解析为 RoverMap(此逻辑和之前一致)
mRoverMap = MapppUtils.loadPFD2RoverMap(fileInputStream);
//TODO 自定义操作
//释放 service 层资源
ShareMemoryApi.getInstance().releaseGetMapPgmPFD();
}
/**
* 共享内存修改 map.pgm 文件,测试代码
*/
private void setMapPgmPFD(String mapName,RoverMap roverMap) {
byte[] bytes = MapUtils.saveRoverMapToPFDData(roverMap);
boolean result = ShareMemoryApi.getInstance().setMapPgmPFD(mapName, bytesT);
Log.d(TAG, "setMapPgmPFD: result=" + result);
}
如果有相关需求,请拷贝或参考示例代码中NavFragment部分代码,最终可把机器人中的地图、点位信息读出并展示成如下形式。下载代码

| 豹小秘 | 豹小秘2 | mini | 招财豹 | 招财豹Pro | 豹小秘DP |
| 是 | 是 | 是 | 是 | 是 | 否 |
打开/关闭 雷达数据上报
方法名称:setNavigationLineData 调用方式:
RobotApi.getInstance().setNavigationLineData(reqId, enabled);
参数
- enabled:true则启用雷达数据上报;false则关闭雷达数据上报
雷达数据监听
RobotApi.getInstance().registerStatusListener(Definition.STATUS_LINE_DATA,
new StatusListener(){
@Override
public void onStatusUpdate(String type, String value) {
List<Pose> list = GsonUtil.getGson().fromJson(data, new TypeToken<List<Pose>>() {
}.getType());
}
});
注意,需要setNavigationLineData开启雷达数据上报,才会有数据;使用完毕后,关闭雷达数据上报,且unregisterStatusListener,释放资源