对于Test_5项目中py文件的一些说明
multimode
- 这个文件夹放的是符号接地部分的的代码,这部分的代码的主要功能是返回行为树中条件节点判断的结果,目前是以布尔值作为返回值,后续可以做更改,这部分在
test.py
中:
my_list = pred.cpu().numpy().tolist()[0]
my_dic = {'is_insert': True if int(my_list[0]) == 1 else False,
'is_open': True if int(my_list[1]) == 0 else False,
'is_hold': True if int(my_list[2]) == 1 else False,
'hand_free': True if int(my_list[2]) == 0 else False,
'is_close_to': True if int(my_list[3]) == 0 else False}
print("dic:", my_dic)
return my_dic[condition_name]
- 项目中只在
FunctinList.py
中对符号接地有调用,相关方法为judge_condition
:
def judge_condition(condition_name, parm):
from multimodal import test
for dic in FunctionList.condition_function_list:
if dic['name'] == condition_name:
# 由于前端任务生成的条件会按字典序排列参数
# 这里将参数调整为仿真端规定的顺序
n_parm = dic['parm'].copy()
print('parm: ', parm)
print('n_parm: ', n_parm)
for key in n_parm.keys():
if key not in parm:
raise Exception('Parm not exists')
n_parm[key] = parm[key]
classic = test.classic()
judge_res = classic.classic(condition_name, n_parm)
print('condition ' + condition_name)
print('judge_res: ', judge_res)
return judge_res
raise Exception('Condition not exists')
- 值得一提的是,由于符号接地和主函数部分都要与Vrep仿真端建立连接,而建立多个连接容易出现错误,目前的做法是让这两种共用一个连接,即
VrepAPI.py
中建立的连接。又由于一些复杂的原因,把import放到开头就会报错(我分析原因可能是multimode中的Get_State.py
需要在一开始就建立好连接,传回vrep对象,而项目目前的逻辑是开启前端页面后才会调用get_list建立连接,两者时间上的冲突造成的),所以目前的做法是在调用方法的时候再import,蠢是蠢了点,不过管用就行!
FunctionList.py
- 这个文件的主要功能是在与仿真端Vrep建立连接后与其通信,如下达动作指令、获取实时状态等。这个文件的上一个版本的所有动作函数和条件函数都是写死的,经过我们修改后变成了
action_excute
和judge_condition
两个函数。
FunctionList_2.py
- 这个文件是与符号接地对接的结果之一,仍然是由于两部分需要共享一个连接,在对接的时候我们就将符号接地部分需要与仿真端通信的函数集中抽取出来成为一个py文件。
写文档的时候突然想到,这部分好像放到mulitmode里更合理一点。
newbot.py
- 这个文件的主要功能是与前端的交互和行为树算法的一些实现(扩展子树、冲突检测等等)。在前端发出'/get_list'请求后,会调用这个文件中的
newbot
方法,这也是开启前端界面后调用的第一个方法,因此会比较重要,一些列表的初始化的工作也放到了这个方法里(动作列表、条件列表等)。
VrepAPI.py
- 这个文件的作用就是单纯的与Vrep建立连接,为了保持一致性,我们建议如果需要新写与Vrep通信的方法,尽量不要写到这个文件中,而是写到
FunctionList.py
这样的文件中。
vrep.py
- 这个文件和
vrepConst.py
是配套的,和multimode中的sim.py
与simConst.py
相同,它们都是Vrep官方提供的库函数,一般来说是不需要修改的。
- 但是我们修改了。
- 在与符号接地对接的时候,我们遇到了很离谱的事情。在手动建立好与Vrep的连接并开始仿真后,在multimode文件夹与根目录下分别运行一样的代码(即
test.py
)来从仿真端获取用于符号接地判断的数据,结果居然不一致(multimode文件夹下运行就是对的,根目录下运行就是空的)。
- 经过排查,我发现在multimode文件夹下运行代码,
vrep.py
找到的就是multimode下的remoteApi.so
,而在根目录下运行代码,vrep.py
找到的就是根目录下的remoteApi.so
。
- 机智的我马上想到,只要用multimode下的
remoteApi.so
替换根目录下的remoteApi.so
不就行了吗,诶,还真不行!
- 无奈之下,我只能修改了
vrep.py
中的源码,强行让它使用multimode下的remoteApi.so
,更改如下所示:
# load library
libsimx = None
try:
print("system:", platform.system())
if platform.system() == 'Windows':
libsimx = CDLL("./remoteApi.dll")
elif platform.system() == 'Darwin':
libsimx = CDLL("./remoteApi.dylib")
else:
libsimx = CDLL("./multimodal/remoteApi.so") # 之前是"./remoteApi.so"
其他文件
- 其他的文件我们基本没有结构性的调整与修改,与上一版功能和效果是一样的,可以直接参考上一版的文档和代码中的注释,在此就不再赘述。