为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

米琪卡哇伊 2023-08-15 16:43:56
假设我们有一个并发 SMACH 容器sm_con,其中包括两个状态机SM1和SM2。我需要找到一种方法,让SM1不断更新一些数据,让SM2访问(并最终修改)相同的数据。我考虑通过将sm_con的用户数据作为输入和输出键传递给SM1和SM2来解决这个问题,希望如果SM1修改数据,它会自动覆盖sm_con的用户数据(有点像在 C++ 中使用指针),但这并不'不工作。相应的代码如下所示:import smachimport smach_rosimport rospyclass 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, outcomes=['successful', 'preempted']):        smach.State.__init__(self, outcomes, 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'})运行此代码,输出“ test 1: ... ”显示SM1内部用户数据增加,而输出“ test 2: ... ”显示SM2不会访问增加的数据,因为输出仍为0。如何修改SM1中的某些数据并访问SM2中修改后的数据?
查看完整描述

1 回答

?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

我找到了一种使用可变对象的解决方法,它看起来像下面这样:

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, outcomes=['successful', 'preempted']):

        smach.State.__init__(self, outcomes, 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[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', 'preempted'], 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()

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



查看完整回答
反对 回复 2023-08-15
  • 1 回答
  • 0 关注
  • 123 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信