实习工作交接
仿真端规范说明
数据传输部分
仿真端需要通过设置string类信号的方式,传五项数据给python进程;
五项数据分别为:objectName,robotCommand,actionList,conditionList,skillExpandList;
它们相当于仿真端对这个场景的形式化描述,且需要一定的格式规范;
注意:上面五个名字同时也被强制规定为五项数据的信号名。
1.objectName
仿真端所有物体的名字,需要以列表的形式传送,如下为例:
objNameSignal=sim.setStringSignal('objectName','[\'newbot_vehicle_target_position\',\'newbot_reference\','..
'\'left_hand\',\'right_hand\',\'cup_2\',\'cup_1\',\'door_1_f\','..
'\'door_1_b\',\'location_1\',\'table\']')
2.robotCommand
控制信号的名字以及取值,每一组为列表的一项,样例场景中只有一项'armCommand' ;
name:控制信号的名字;
value:控制信号的取值列表,需要以string:int的形式同时给出字符串值和整数值;
parmNameSignal=sim.setStringSignal('robotCommand','[{\'name\':\'armCommand\','..
'\'value\':{\'armInit\':1,\'open_door\':2,\'grasp\':3,'..
'\'pour_coffee\':4,\'put_down\':5,\'move_to\':6}}]')
3.actionList
动作列表,代表当前场景下机器人可执行的动作;
name:动作名字,注意需要与robotcommand中的value中的字符串名字一一对应;
parm:动作参数;
command:执行该动作需要设置的信号名字;
subactions:获取该动作的子动作的信号的名字;
value:动作对应的整形值,需要与robotCommand中的value中的整数值一一对应;
actionListSingal=sim.setStringSignal('actionList',
'{\'name\':\'armInit\',\'parm\':{},\'command\':\'\',\'subactions\':\'\',\'value\':1},'..
'{\'name\':\'move_to\',\'parm\':{\'location_id\':\'\'},\'command\':\'armCommand\',\'subactions\':\'wheelOrder\',\'value\':6},'..
'{\'name\':\'grasp\',\'parm\':{\'object_id\':\'\'},\'command\':\'armCommand\',\'subactions\':\'behaviorOrder\',\'value\':3},'..
'{\'name\':\'put_down\',\'parm\':{\'hand_id\':\'\'},\'command\':\'armCommand\',\'subactions\':\'behaviorOrder\',\'value\':5},'..
'{\'name\':\'open_door\',\'parm\':{\'door_id\':\'\'},\'command\':\'armCommand\',\'subactions\':\'behaviorOrder\',\'value\':2}')
4.conditionList
条件列表,代表当前场景下可能要判断的条件;
name:条件名字;
parm:条件参数;
id:条件名对应的取值,python进程将条件设置为该值,代表要向仿真端询问该条件。
conditionListSignal=sim.setStringSignal('conditionList','{\'name\':\'condition_init\',\'parm\':{},\'id\':0},'..
'{\'name\':\'is_robot_close_to\',\'parm\':{\'location_id\':\'\'},\'id\': 1},'..
'{\'name\':\'path_free\',\'parm\':{\'location_id\':\'\'},\'id\': 2},'..
'{\'name\':\'is_open\',\'parm\':{\'door_id\':\'\'},\'id\': 3},'..
'{\'name\':\'is_hold\',\'parm\':{\'object_id\':\'\',\'hand_id\':\'\'},\'id\': 4},'..
'{\'name\':\'hand_free\',\'parm\':{\'hand_id\':\'\'},\'id\': 5},'..
'{\'name\':\'is_ready\',\'parm\':{\'object_id\':\'\',\'object_name\':\'\'},\'id\': 6}')
5.skillExpandList
子动作扩展列表,这是为了满足前端展示当前详细动作的需求;
事实上其为字典,键代表该动作对应的取值,值作为该动作分解成的子动作序列;
注意,子动作一定要按机器人执行该动作的实际顺序定义,且在机器人执行动作的部分,在每进行一个子动作前需要发送一次序列信号,表示当前动作下,正在进行第几个子动作。
skillExpandListSignal = sim.setStringSignal('skillExpandList',
'{2: {\'skill\': \'open_door\', \'behavior\': [\'RaiseBothArms\', \'StretchBothArms\', \'PushDoor\', \'Recovery\']},'..
'3: {\'skill\': \'grasp\', \'behavior\': [\'RaiseArm\', \'CloseToObject\', \'GraspObject\', \'KeepHold\']},'..
'4: {\'skill\': \'PourCoffee\', \'behavior\': [\'TakeOutObject\', \'Pour\', \'LayBack\', \'KeepHold\']},'..
'5: {\'skill\': \'PutDown\', \'behavior\': [\'Adjust\', \'PutDownObject\', \'AwayFromObject\', \'TakeBackArm\']},'..
'6: {\'skill\': \'move_to\', \'behavior\': [\'move\']}}')
代码执行部分
动作执行逻辑
1.信号规范
仿真端通过监听信号来判断机器人要执行的动作。
python以command + parm
的形式传输信号;
command信号:名字与仿真端传过来的actionList中相应的command字段相同;
parm信号:名字需要按actionParaCommandX
的格式,其中X代表动作的第几个参数;
如下为例:
armSignal=sim.getIntegerSignal('armCommand')
actionParaSignal=sim.getIntegerSignal('actionParaCommand0')
actionParaSignal1=sim.getIntegerSignal('actionParaCommand1')
actionParaSignal2=sim.getIntegerSignal('actionParaCommand2')
2.执行规范
动作的执行需要按照一定的规范进行,如下为例:
if (armSignal==grasp) then
--参数判断
if (actionParaSignal==sim.getObjectHandle('cup_1')) then
print("rightArmGraspCup")
--更新behaviorOrder
sim.setIntegerSignal('behaviorOrder',1)
sim.rmlMoveToJointPositions(armJoints,-1,nil,nil,fkSpeed,fkAccel,fkJerk,raiseRightHand,nil)
sim.rmlMoveToJointPositions(armJoints,-1,nil,nil,fkSpeed,fkAccel,fkJerk,rightGraspCup,nil)
sim.setIntegerSignal('behaviorOrder',2)
sim.rmlMoveToJointPositions(armJoints,-1,nil,nil,fkSpeed,fkAccel,fkJerk,rightFalling,nil)
sim.rmlMoveToJointPositions(armJoints,-1,nil,nil,fkSpeed,fkAccel,fkJerk,rightFalling2,nil)
sim.setIntegerSignal('behaviorOrder',3)
sim.rmlMoveToJointPositions(armJoints,-1,nil,nil,fkSpeed,fkAccel,fkJerk,rightMoveClose,nil)
closeGripper()
sim.setIntegerSignal('behaviorOrder',4)
sim.rmlMoveToJointPositions(armJoints,-1,nil,nil,fkSpeed,fkAccel,fkJerk,keepRightGrasp,nil)
sim.setIntegerSignal('behaviorOrder',-1)
sim.wait(2.0)
--设置状态
--is_hold = True
rh_have_cup_type = 1
armSignal=sim.setIntegerSignal('armCommand',1)
actionParaSignal=sim.setIntegerSignal('paraCommand',0)
--信号初始化
print("rightArmGraspCupFinish")
elseif (actionParaSignal==sim.getObjectHandle('cup_2')) then
...........................
end
end
参数判断:动作执行逻辑中可能会根据参数的取值进行条件判断,如动作是'grasp',参数是'cup_1',仿真端应该命令机器人执行grasp cup_1的动作;当然仿真端也可以设置成grasp_cup_1和grasp_cup_2两个动作,修改发送的actionList即可。
更新behaviorOrder:为了前段展示的需要,机器人在执行一个动作的子动作前,需要发送将要执行的子动作序号,信号名字与仿真端传过来的skill_expand_list中相应的subactions字段相同;
设置状态:这一步是可选的,如果选择使用接地网络判断条件,而不是在仿真端维护状态列表,则这一步不需要;否则在每个动作执行完成后,仿真端需要手动更新以维护状态列表;
信号初始化:在每个动作执行结束后,仿真需要将动作信号初始化,因为python进程会根据此判断动作执行完成,否则python进程会一直认为动作还在进行而等待;同时记得将动作的变量也初始化,否则下一个循环机器人还会执行这个动作。
条件判断逻辑
若采用符号接地判断条件,此步骤可省略。
1.状态列表规范
仿真端需要自行维护状态列表,当执行动作的时候进行相应的维护,条件列表如下为例:
--object status
cup_type = 0 --杯子是否满了
door_type = 0 --门是否开了
lh_have_pot_type = 0 --左手是否拿着东西
rh_have_cup_type = 0 --右手是否拿着东西
2.信号规范
仿真端通过监听信号判断python进程是否需要向其发送条件判断请求。
python同样以command + parm
的形式传输信号;
command信号:由于条件判断只有一个类型,条件判断的信号名强制为conditionCommand
parm信号:名字需要按conditionParaCommandX
的格式,其中X代表条件的第几个参数;
如下为例:
conditionSignal=sim.getIntegerSignal('conditionCommand')
conditionParaSignal0=sim.getIntegerSignal('conditionParaCommand0')
conditionParaSignal1=sim.getIntegerSignal('conditionParaCommand1')
3.判断规范
仿真端根据python传来的条件类型,参数,和自己当前的状态列表,判断条件的正确与否,并以设置信号的形式返回给python进程。
如下为例:
if(conditionSignal == is_hold)then
--print('is_hold')
sim.wait(0.5)
if(conditionParaSignal1 == sim.getObjectHandle('left_hand'))then
if(lh_have_pot_type == 1)then
condition_result = sim.setIntegerSignal('conditionResult', 1)
else
condition_result = sim.setIntegerSignal('conditionResult', 0)
end
elseif(conditionParaSignal1 == sim.getObjectHandle('right_hand'))then
if(rh_have_cup_type == 1)then
condition_result = sim.setIntegerSignal('conditionResult', 1)
else
condition_result = sim.setIntegerSignal('conditionResult', 0)
end
else
condition_result = sim.setIntegerSignal('conditionResult', 0)
end
--信号重置
conditionSignal=sim.setIntegerSignal('conditionCommand',0)
end
end
conditionResult:代表返回结果的信号的名字强制规定为conditionResult;
信号重置:在条件判断结束后一定要将条件判断信号重置为初始值,否则仿真端会不断进行条件判断,并造成结果信号被反复修改。