我一直在努力解决这个问题。我的问题非常具体,所以请不要使用" 发布ROS教程页面的链接!注意: "段落显示如何传递可变对象(除非你告诉我一些我错过的东西)。我想知道是否有人能够在SMACH状态中来回正确传递可变对象,而不会遇到任何错误。
我写了一个特别简单而无用的程序来解释我试图做的事情。我可以发布这个例子的代码(不幸的是,对于那些以前使用过SMACH的人来说,这并不奇怪,这是一段很长的代码)。所以现在我将尽力解释它,并在我的例子的图像中加入[link]。我创建了两个python脚本。每个脚本包含该类的单个类和对象(使用一些基本方法)。我在每个脚本中创建一个发布者和订阅者,其中一个脚本发送消息(会话),而另一个脚本侦听(听到)消息。最后,讲话者将两个FSM标记为关闭。如果有人想要完整的代码示例,请告诉我......
下面的代码片段显示了smach状态和转换:
# begin sm
with sm:
smach.StateMachine.add('LOAD', loadFSM(),
transitions={'LOADED':'SENDMSG'})
smach.StateMachine.add('SENDMSG', startMSG(),
transitions={'SENT':'SENDMSG',
'ENDING':'END'})
smach.StateMachine.add('END', stopFSM(),
transitions={'DONE':'complete',
'ERRED':'incomplete'})
下面的代码片段显示了一个smach状态(loadFSM):
class loadFSM(smach.State):
def __init__(self):
smach.State.__init__(self, outcomes=['LOADED'],
output_keys=['talker_obj'],
input_keys=['talker_obj'])
# Initialise our talker object
self.talker = Talk()
def execute(self, userdata):
rospy.loginfo("talker state: Loading fsm")
self.talker.init_publish()
self.talker.init_subscribe()
userdata.talker_obj = self.talker
return 'LOADED'
我收到的错误(使用Ubuntu 14.04,ROS indigo和python 2.7,不太确定,但我相信同样的错误也发生在动力学中)只发生在状态转换期间,当然内省服务器不起作用(不显示状态转换)。错误是;
1。 "线程中的异常sm_introViewer:status_publisher:"
2。 "无法执行转换回调:Traceback(最近一次调用
最后):文件
" /opt/ros/indigo/lib/python2.7/dist-packages/smach/container.py" ;,
第175行,在call_transition_cbs cb中(self.userdata,
self.get_active_states(),* args)"
我还需要补充一点,我的简单有限状态机示例实际上已成功运行并完成,即使我的项目的2个较大的FSM也完成了。但是,当FSM在我的项目中有许多状态时,有时我的模拟会失败。如果他们认为这些错误是原因,或者他们知道我没有在状态之间正确传递对象这一事实,那么我想知道任何广泛使用SMACH的人。
先谢谢,
Tiz
答案 0 :(得分:1)
过去我遇到过类似的问题。如果我没记错的话,userdata
只能处理基本类型(int,string,list,dict,...),而不能处理任意对象。
我通过将对象传递给状态类的构造函数而不是使用userdata来解决它,例如:
class myState(smach.State):
def __init__(self, obj):
smach.State.__init__(self, outcomes=['foo'], ...)
self.obj = obj
...
然后初始化如下:
obj = SomeClass()
with sm:
smach.StateMachine.add('MY_STATE', myState(obj),
transitions={'foo':'bar'})
它不是很好,因为它绕过了userdata概念,但它可以工作。