微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在SMACH并发容器的不同状态下使用相同的数据

如何解决在SMACH并发容器的不同状态下使用相同的数据

假设我们有一个并发的SMACH容器 sm_con ,其中包括两个状态机 SM1 SM2 。我需要找到一种方法,使 SM1 不断更新某些数据,并使 SM2 访问(并最终修改)相同的数据。我想通过将 sm_con 用户数据传递给 SM1 SM2 作为输入和输出键来解决这个问题,希望如果 SM1 修改自动覆盖 sm_con 用户数据的数据(有点像在c ++中使用指针),但这不起作用。

相应的代码如下:

import smach
import smach_ros
import rospy

class st1(smach.State):
    def __init__(self,outcomes=['successful','preempted']):
        smach.State.__init__(self,outcomes,input_keys=['in_test'],output_keys=['out_test'])

    def execute(self,userdata):
        if self.preempt_requested():
            self.service_preempt()
            return 'preempted'
        rospy.logerr('test 1: '+str(userdata.in_test))
        userdata.out_test=userdata.in_test+1
        return 'successful'

class st2(smach.State):
    def __init__(self,input_keys=['in_test'])

    def execute(self,userdata):
        #time.sleep(2)
        if self.preempt_requested():
            self.service_preempt()
            return 'preempted'
        rospy.logerr('test 2: ' + str(userdata.in_test))
        return 'successful'


if __name__=="__main__":
    rospy.init_node('test_state_machine')

    sm_con = smach.Concurrence(outcomes=['success'],default_outcome='success'
                               )
    sm_con.userdata.testdata = 0
    with sm_con:
        sm_1 = smach.StateMachine(outcomes=['success','preempted'],input_keys=['testdata'],output_keys=['testdata'])
        with sm_1:
            smach.StateMachine.add('ST1',st1(),remapping={'in_test': 'testdata','out_test': 'testdata'},transitions={'successful': 'ST1'})

        sm_2 = smach.StateMachine(outcomes=['success',input_keys=['testdata'])
        with sm_2:
            smach.StateMachine.add('ST2',st2(),remapping={'in_test':'testdata'},transitions={'successful': 'ST2'})

        smach.Concurrence.add('SM1',sm_1)
        smach.Concurrence.add('SM2',sm_2)

    # Execute SMACH plan
    outcome = sm_con.execute()
    print('exit-outcome:' + outcome)
    # Wait for ctrl-c to stop the application
    rospy.spin()

运行此代码输出' test 1:... '显示,在 SM1 中,用户数据递增,而输出' test 2 :。 .. '表明 SM2 不会访问增量数据,因为输出仍为 0

如何在 SM1 修改某些数据并在 SM2 中访问已修改的数据?

解决方法

我发现使用here这样的可变对象来解决此问题。

在上面的代码上应用后,它将类似于以下内容:

import smach
import smach_ros
import rospy

class st1(smach.State):
    def __init__(self,outcomes=['successful','preempted']):
        smach.State.__init__(self,outcomes,input_keys=['in_test'])

    def execute(self,userdata):
        if self.preempt_requested():
            self.service_preempt()
            return 'preempted'
        rospy.logerr('test 1: '+str(userdata.in_test))
        userdata.in_test[0]=userdata.in_test[0]+1
        return 'successful'

class st2(smach.State):
    def __init__(self,userdata):
        #time.sleep(2)
        if self.preempt_requested():
            self.service_preempt()
            return 'preempted'
        rospy.logerr('test 2: ' + str(userdata.in_test[0]))
        return 'successful'


if __name__=="__main__":
    rospy.init_node('test_state_machine')

    sm_con = smach.Concurrence(outcomes=['success'],default_outcome='success'
                               )
    sm_con.userdata.testdata = [0]
    with sm_con:
        sm_1 = smach.StateMachine(outcomes=['success','preempted'],input_keys=['testdata'])
        with sm_1:
            smach.StateMachine.add('ST1',st1(),remapping={'in_test': 'testdata'},transitions={'successful': 'ST1'})

        sm_2 = smach.StateMachine(outcomes=['success',input_keys=['testdata'])
        with sm_2:
            smach.StateMachine.add('ST2',st2(),remapping={'in_test':'testdata'},transitions={'successful': 'ST2'})

        smach.Concurrence.add('SM1',sm_1)
        smach.Concurrence.add('SM2',sm_2)

    # Execute SMACH plan
    outcome = sm_con.execute()
    print('exit-outcome:' + outcome)
    # Wait for ctrl-c to stop the application
    rospy.spin()

由于这只是一种解决方法,请参阅我相应的问题帖子here以获取更多信息。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。