在SMACH Concurrentcontainer的不同状态下使用相同的数据

2024-10-03 00:18:48 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我们有一个并发SMACH容器sm_-con,它包括两个状态机SM1SM2。我需要找到一种方法,让SM1不断更新一些数据,让SM2访问(并最终修改)相同的数据。我想通过将sm_-con的用户数据作为输入和输出键传递给SM1SM2来解决这个问题,希望如果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, 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'})

        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()

运行此代码时,输出“test1:'显示在SM1内部,当输出'测试2:<“eem>”显示SM2不会访问递增的数据,因为输出保持0

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


Tags: 数据intestselfkeyscontestdatasm
1条回答
网友
1楼 · 发布于 2024-10-03 00:18:48

我找到了一个解决方法,使用了可变对象,如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, 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()

由于这只是一个解决办法,请参阅我的相应问题帖子here以了解更多信息

相关问题 更多 >