Robot
类介绍
继承
1 | class Robot : public Plug |
Robot是Plug的子类。
私有属性
1 | private: |
函数
AnalyseDomain
接受信息表里的信息,将它们储存在我们自己设定的容器中(预处理阶段)
domain:环境表结构体(可在global中看到)
1 | //环境表结构体 |
domaintype:枚举类型(env和ins两种类型)
1 | enum DomainType //环境表和任务表中都含有domain结构体,所以会有不同的处理 |
chosen
标记当前正在处理 domain
的第几个字段。chosen先从1开始。由(:domain (at 0 0) (sort 1 human) (hold 0))
可以看出,domain有三个字段。
如果 sx
非空,则跳到sx的下一个节点 。
否则,遍历 S-expression 的每个节点,逐个处理内容。
1 | case 1: |
若chosen为1,则是第一个字段,将第一个值赋值给 keyword
若chosen为2,将第二个值赋值给 id
若chosen为3, 将第三个值赋值给 other
每次处理一个完整的 domain
,将处理过的链表信息加入 vector_tmp_domain
,然后重置chosen为1,将链表指针移动至下一个,继续循环,赋值判断。
最后这个函数返回值是domain类型的vector容器。
DowithVectorDomain
处理容器(vector_tmp_domain)信息里的每一项。
如果domaintype为env(环境),将机器人先存到容器里,毕竟这个阶段肯定是没有其他物体的。
如果domaintype为instr(任务),肯定会有一个物体X,先将这个物体存到容器中。
1 | vector<domain>::iterator pr; |
pr为表的迭代器,然后遍历所有表,如果某个物体的ID为Y,那么肯定是第二个物体,则再将它存到容器中。
解析关键词
注意:下列一切操作都是基于遍历链表的前提
首先,将X和Y映射到对应vector_tmp_object容器的下标
1 | if (domain_type == DOMAINTYPE_INS) { |
如果在指令语言下,vector_tmp_object[0]和vector_tmp_object[1]分别表示第一个物体和第二个物体。
如果在环境语言下,通过atoi函数(它的主要功能是将字符串转换为整数)将X和Y转换成整数,从而得到下标。
然后,检查一下vector_tmp_object的容量,如果它的容量vec_index比id还小,那么会引发数组越界错误,我们就需要在空缺的那一部分(id-vec_index)补充元素,防止越界。
下面,通过一个很多分支的if判断来分类关键词。
如果keyword为sortx
如果是环境语言条件下,那么已经分配过了,于是需要一个空的Object对象tmp去给这个下标的数组内容占位,同时由于占了一个位置,容器的容量vecindex也需要加一。
这段代码主要的作用还是防止有些物体不是按照1234….顺序递增而导致的下标不符的错误。
1
2
3
4
5if (domain_type == DOMAINTYPE_ENV) { //如果是来自指令的则已经分配过了
vector_tmp_object.push_back(tmp); //如果是物体分配一个空间
if (domain_type == DOMAINTYPE_ENV)
++vec_index;
}否则,根据物体的ID分配相应的种类,如HUMAN,PLANT,COUCH等等
如果keyword为at
更新位置
如果id是0,代表机器人
at表示位置,因此需要更改机器人此刻的位置,使用SetLocation函数,atoi(other.c_str())表示解析位置,并转换成整数。
如果id不为0,是普通物体
如果keyword为color
根据颜色分配相应的种类
如果keyword为type
分配container
如果keyword为inside
分配装在大物体里面的小物体
更改两个参数:inside参数和location参数,即小物体在哪个物体里面和小物体此刻的位置
如果keyword为on
分配物体的位置
如果keyword为near
分配物体的位置
1
vector_tmp_object[id].SetPosition(vector_object[id].GetPosition() | uint(atoi(other.c_str())));
这段代码用到了或运算,为了是不覆盖原有的位置状态,合并表示多个位置关系
如果keyword为opened
分配门是开的状态
如果keyword为closed
分配门是关的状态
如果keyword为plate
如果id=0,没有物体
如果id不为0,有物体
先将物体的id记录在临时创建的Object类对象obj_tmp中,然后再根据obj_tmp设置机器人盘子里的物体。
如果keyword为hold
跟上面plate的操作一致。
更新
首先获得手里和盘子里的物体id。
如果手里的物体不为空,更新机器人手里的物体,将它的id设置成此处遍历到的物品id,然后再将物体的位置更新为机器人的位置。
盘子里的物体同上。
StoreObject
传入信息表以及表的类型(env or ins)
将vector_tmp_domain
容器中的信息按函数DowithVectorDomain
的方法塞入vector_tmp_object
容器。
=============================================================
许春升 2025.1.22