- zip包存储着四种数据:概述、地图数据、位置信息和绑定信息。
- 编辑地图栅除了位置A,那保存后,以位置A为first的绑定都要将清除。为避免再去建立位置和小程序之间绑定,如果只是修改位置名称、x、y、theta,不要删除该位置,就地编辑。
- 保存地图时,会不会检查是否存在aplt指定的小程序?1)卸载小程序时。2)修改了一个已存在的绑定。
为直观,本文用一个示例来描述地图rsp。
图1中高亮部分是92字节的trsp_rosmap92bytes。
一、第一部分:rsp头(48字节)
Tag3-H4=3(zipt_rosmap)
zip包中数据版本:0.0.1-1677068961(0x63f60aa1)。0.0.1是zip包中版本格式,可认为是地图的存储格式版本。目前是0.0.1。1677068961是此地图的最后修改时间,用C函数time(nullptr)生成。
rose版本:1.0.1。
bundleid:com.kos.launcher。com.kos.launcher这个app生成了此个文件。
zip包字节数:0xa011 = 40977。可算出该rsp文件字节数:48 + 40977 + 20 = 41045。而40977由四部分组成。
次序 | 内容 | 字节数 | |
#1 | 描述信息 | sizeof(trsp_rosmap92bytes)(92) | 指示后面三个数据块有多少字节 |
#2 | 地图数据 | 40599 | |
#3 | 位置信息 | 82 | |
#4 | 绑定信息 | 204 |
二、zip包
2.1 地图描述信息
地图描述信息是一个trsp_rosmap92bytes结构。
#define RSP_MAP_MAXDESCBYTES 55 struct trsp_rosmap92bytes { char desc[RSP_MAP_MAXDESCBYTES + 1]; double charge_x; double charge_y; double charge_theta; uint32_t map; uint32_t positions; uint32_t binds; };
针对示列,它从0x30开始,占92字节。
- desc:用于描述该地图使用场景的一个字符串。56字节。
- charge_x/y/theta:指示充电位置在地图中位置。3个double占24字节。加上desc占80(0x50)字节,接下map字段从0x80开始。
- map:(0x9e97)40599。map部分40599字节。
- positions:(0x52))82。positons部分82字节。82字节描述一个位置(trsp_rosmapposition),因而这地图只存在一个位置。
- binds:(0xcc)204。binds部分204字节。68字节描述一个绑定(trsp_rosmapbind),这地图存在三个绑定。又因为只有一个位置,这个绑定应该都是绑到那个唯一位置。
2.2 map数据
封装地图数据用的是nav_msgs::OccupancyGrid结构,该部分就是OccupancyGrid序列化后的二进制数据。
针对示例,从0x8c开始,即“19 01 00 00 d3 93”后的40599()字节是地图数据。
2.3 位置信息
这里存储着位置数组,一个trsp_rosmapposition结构封装一个位置。针对示例,从0x9f23开始。图2中高亮部分是zip包中的位置信息。和其它类型rsp一样,最后20字节是SHA1校验数据。
#define RSP_MAP_MAXPOSNAMEBYTES 20 struct trsp_rosmapposition { char uuid[36 + 1]; // 38a08106-e2c9-48ed-a19f-874f5690a7bd. char name[RSP_MAP_MAXPOSNAMEBYTES + 1]; double x; double y; double theta; };
- uuid:ce1d26c6-768e-4402-98ec-0071463c10bd
- name:ble
- x/y/theta:2.95833/2.388888/1.57079
2.4 绑定信息
这里存储着绑定数组,一个trsp_rosmapbind结构封装一个绑定。图1从0x9f75(0x9f23 + 82)开始。
#define RSP_MAP_MAXBINDIDBYTES 23 struct trsp_rosmapbind { uint32_t idx; char aplt[RSP_MAXAPPLETIDBYTES + 1]; // aplt.leagor.basic(studio) char id[RSP_MAP_MAXBINDIDBYTES + 1]; // air_conditioner };
既然是绑定,那需要有两方,这两方指的是地图中位置和小程序中目标物,binds存储着着绑定信息。
绑定是这么个映射:positions[idx] --> aplt+id
- idx:0。地图中的位置。值是在位置数据中索引。只有一个位置,那只能是0。
- aplt:aplt.leagor.basic(studio)。小程序+目标物中的小程序。
- id:ble。小程序+目标物中的目标物标识。
示例中有三个绑定。
idx(映射中first) | aplt + id(映射中second) | |
#1 | 0 | aplt.leagor.studio(studio) + ble |
#2 | 0 | aplt.leagor.blesmart(studio) + ble |
#3 | 0 | aplt.leagor.blesmart(studio) + rk3399 |
编辑地图栅除了位置A,那保存后,以位置A为first的绑定都要将清除。为避免再去建立位置和小程序之间绑定,如果只是修改位置名称、x、y、theta,不要删除该位置,就地编辑。
保存地图时,会不会检查是否存在aplt指定的小程序?1)卸载小程序时。2)修改了一个已存在的绑定。
二、tros_map
app用一个tros_map封装了从rsp读出的地图据。
在tros_map中有两个成员和位置/绑定有关。
class tros_map { std::map<std::string, tmap_position> positions; // Use bind_uuid_map to improve the lookup effect. // (aplt.leagor.basic+ble) --> position's uuid std::map<tmap_position::tbind, std::string> bind_uuid_map; };
positions结构和rsp地图中的较为相似,以postions为key,然后tmap_posiion封装了该位置的信息,包括绑定情况。
bind_uuid_map则是一个为方便方便管理绑定结构而加的变量。first是绑定dst,second是位置的uuid。