zoukankan      html  css  js  c++  java
  • ROS之动作(计时器进阶)

    ---恢复内容开始---

    上次的代码只有简单的发送目标和接受结果,这次将实现终止目标、处理打断请求和实时反馈的功能

    fancy_action_server.py

     1 #!/usr/bin/env python                                                             
     2 
     3 import rospy
     4 
     5 import time
     6 import actionlib
     7 from basic.msg import TimerAction , TimerGoal , TimerResult , TimerFeedback        #这里导入生成的包
     8 
     9 def do_timer(goal):                                          #创建处理函数
    10     start_time = time.time()                                     #记录当前的时间
    11     update_count = 0                                          #增加这份额变量统计一共发了多少次反馈
    12 
    13     if goal.time_to_wait.to_sec() > 60.0:                             #增加的错误检查,当时长大于60则则处理错误
    14         result = TimerResult()                                    #创建一个TimerResula的类型
    15         result.time_elapsed = rospy.Duration.from_sec(time.time() - start_time)       #将运行的时间从秒转换为ROS的Duration类型
    16         result.updates_sent = update_count                            #将反馈的次数返回
    17         server.set_aborted(result , "Timer aborted due to too-long wait")           #给予提示信息
    18         return
    19 
    20     while(time.time() - start_time) < goal.time_to_wait.to_sec():               #通过了错误检查后,当完成条件未达到时,则进入循环执行一下程序,,,可以在动作执行过程中进行一些操作如检查是否打断,提供反馈
    21         if server.is_preempt_requested():                            #检查是否打断,(即在客户端执行前一个动作时,又发送了新的目标)函数会返回True
    22             result = TimerResult()                                #此时需要填充一个result,同时返回提示信息
    23             result.time_elapsed = rospy.Duration.from_sec(time.time() - start_time)             
    24             result.updates_sent = update_count                           
    25             server.set_preempted(result , "Timer preempted")              
    26             return
    27 
    28         feedback = TimerFeedback()                              #创建TimerFeedback类型
    29         feedback.time_elapsed = rospy.Duration.from_sec(time.time() - start_time)  #赋值为处理经过的时间,并从秒转换为ROS的Duration类型
    30         feedback.time_remaining = goal.time_to_wait - feedback.time_elapsed      #赋值还需要等待的时间,用目标时间减去已经运行的时间
    31         server.publish_feedback(feedback)                            #发布反馈给客户端
    32         update_count += 1                                    #增加update_count来表示反馈的次数
    33 
    34         time.sleep(1.0)                                    #进行短暂的休眠,这里使用的是固定休眠时长,这样回导致世界休眠时间过长超过目标时间,
    35 
    36     result = TimerResult()                                  #循环结束后创建TimerResult类型将结果返回,并返回成功的信息
    37     result.time_elapsed = rospy.Duration.from_sec(time.time() - start_time)                #
    38     result.updates_sent = update_count                            #
    39     server.set_succeeded(result , "Timer completed successfully")              #
    40 
    41 rospy.init_node('timer_action_server')                          #初始化节点
    42 server = actionlib.SimpleActionServer('timer' , TimerAction , do_timer,False)    #
    43 server.start()                                          #  
    44 rospy.spin()                                            #

    创建新的客户端,包括对反馈的处理,打断正在执行的目标,以及引发一个终止

    fancy_action_client.py

     1 #!/usr/bin/env python                                                             
     2 
     3 import rospy
     4 
     5 import time
     6 import actionlib
     7 from basic.msg import TimerAction , TimerGoal , TimerResult ,  TimerFeedback
     8 
     9 def feedback_cb(feedback):                                      #创建回调函数,处理反馈信息,这里只是简单将反馈信息打印
    10         print('[Feedback] Time elapsed: %f ' % (feedback.time_elapsed.to_sec()))      #目标已经执行的时间  
    11         print('[Feedback] TIme remaining: %f' % (feedback.time_remaining.to_sec()))    #目标还需要执行的时间
    12 
    13 rospy.init_node('timer_action_client')
    14 client = actionlib.SimpleActionClient('timer',TimerAction)                 #声明节点
    15 client.wait_for_server()                                      #等待服务器的启动
    16 goal = TimerGoal()
    17 goal.time_to_wait = rospy.Duration.from_sec(5.0)                        #发送目标
    18 
    19 client.send_goal(goal ,feedback_cb = feedback_cb)                       #将回调函数作为feedback_cb关键词作为参数,传入send_goal中完成回调的注册
    20 
    21 #time.sleep(3.0)
    22 #client.cancel_goal()
    23 
    24 
    25 client.wait_for_result()
    26 
    27 print('[Result] State: %d' % (client.get_state()))
    28 print('[Result] Status: %s' % (client.get_goal_status_text()))
    29 print('[Result] Time elapsed: %f' % (client.get_result().time_elapsed.to_sec()))
    30 print('[Result] Updates sent: %d' % (client.get_result().updates_sent))

     get_status()函数的返回对应的执行结果类型为actionlib_msgs/GoalStatus 可能的状态有10种,这里只用到了三种:PREEMPTED = 2,SUCCEEDED = 3 , ABORTED = 4,

    [actionlib_msgs/GoalStatus]:
    uint8 PENDING=0
    uint8 ACTIVE=1
    uint8 PREEMPTED=2
    uint8 SUCCEEDED=3
    uint8 ABORTED=4
    uint8 REJECTED=5
    uint8 PREEMPTING=6
    uint8 RECALLING=7
    uint8 RECALLED=8
    uint8 LOST=9

    运行上述代码测试功能

    miao@openlib:~$ rosrun basic fancy_action_client.py 
    [Feedback] Time elapsed: 0.000044 
    [Feedback] TIme remaining: 4.999956
    [Feedback] Time elapsed: 1.001584 
    [Feedback] TIme remaining: 3.998416
    [Feedback] Time elapsed: 2.003138 
    [Feedback] TIme remaining: 2.996862
    [Feedback] Time elapsed: 3.004638 
    [Feedback] TIme remaining: 1.995362
    [Feedback] Time elapsed: 4.006026 
    [Feedback] TIme remaining: 0.993974
    [Result] State: 3
    [Result] Status: Timer completed successfully
    [Result] Time elapsed: 5.007281
    [Result] Updates sent: 5

     将21,22的注释去掉测试。

    miao@openlib:~$ rosrun basic fancy_action_client.py 
    [Feedback] Time elapsed: 0.000043 
    [Feedback] TIme remaining: 4.999957
    [Feedback] Time elapsed: 1.001521 
    [Feedback] TIme remaining: 3.998479
    [Feedback] Time elapsed: 2.003029 
    [Feedback] TIme remaining: 2.996971
    [Result] State: 2
    [Result] Status: Timer preempted
    [Result] Time elapsed: 3.003640
    [Result] Updates sent: 3

    然后测试 将发送时间设为100s

    miao@openlib:~$ rosrun basic fancy_action_client.py 
    [Result] State: 4
    [Result] Status: Timer aborted due to too-long wait
    [Result] Time elapsed: 0.000024
    [Result] Updates sent: 0
  • 相关阅读:
    poj 2528 Mayor's posters (线段树+离散化)
    poj 1201 Intervals (差分约束)
    hdu 4109 Instrction Arrangement (差分约束)
    poj 1195 Mobile phones (二维 树状数组)
    poj 2983 Is the Information Reliable? (差分约束)
    树状数组 讲解
    poj 2828 Buy Tickets (线段树)
    hdu 1166 敌兵布阵 (树状数组)
    Ubuntu网络配置
    Button控制窗体变量(开关控制灯的状态)
  • 原文地址:https://www.cnblogs.com/miaorn/p/11766872.html
Copyright © 2011-2022 走看看