【发布时间】:2021-01-14 10:34:31
【问题描述】:
我只是想在 SMACH 中从 python 启动一个 rosbag-command。我发现这样做的一种方法是使用子流程。我的目标是一旦 rosbag 启动,状态机就会转换到状态 T2(并保持在那里)。
但是,当在 SMACH 状态中使用 subprocess.popen 启动 rosbag 然后使用 rostopic echo 'topic' 时,rosbag 似乎首先正确发布数据,然后突然停止发布数据,并且只有在我使用 Ctrl 结束 SMACH 时+C,rosbag 在停止之前继续发布更多数据。
对此是否有任何合理的解释(我可能错过了一个参数,还是无法让节点以这种方式运行)?或者有没有更好的方法来启动 rosbag 并让其在后台运行?
(顺便说一句,其他一些命令,如一些 roslaunch-commands 在通过 subprocess.popen 启动后似乎停止工作!)
我的代码如下:
#!/usr/bin/env python3
import os
import signal
import subprocess
import smach
import smach_ros
import rospy
import time
from gnss_navigation.srv import *
class t1(smach.State):
def __init__(self, outcomes=['successful', 'failed', 'preempted']):
smach.State.__init__(self, outcomes)
def execute(self, userdata):
if self.preempt_requested():
self.service_preempt()
return 'preempted'
try:
process1 = subprocess.Popen('rosbag play /home/faps/bags/2020-05-07-11-18-18.bag', stdout=subprocess.PIPE,
shell=True, preexec_fn=os.setsid)
except Exception:
return 'failed'
return 'successful'
class t2(smach.State):
def __init__(self, outcomes=['successful', 'failed', 'preempted']):
smach.State.__init__(self, outcomes)
def execute(self, userdata):
#time.sleep(2)
if self.preempt_requested():
self.service_preempt()
return 'preempted'
return 'successful'
if __name__=="__main__":
rospy.init_node('test_state_machine')
sm_1 = smach.StateMachine(outcomes=['success', 'error', 'preempted'])
with sm_1:
smach.StateMachine.add('T1', t1(), transitions={'successful': 'T2', 'failed': 'error'})
smach.StateMachine.add('T2', t2(), transitions={'successful': 'T2', 'failed': 'error', 'preempted':'preempted'})
# Execute SMACH plan
outcome = sm_1.execute()
print('exit-outcome:' + outcome)
# Wait for ctrl-c to stop the application
rospy.spin()
【问题讨论】:
标签: python-3.x multiprocessing subprocess popen state-machine