timed_out_and_back.py を参考にPythonスクリプトでロボットを動かすプログラムを見てみましょう。
スクリプトが終了するときに呼ばれるコールバックon_shutdown()を宣言します。例えば、CtrlCtrl+cキーが押された時に呼ばれます。
1 #!/usr/bin/env python 2 3 import rospyこの2行はPythonスクリプトでROSプログラム書くときのお決まりです
4 from geometry_msgs.msg import Twist5 from math import pi
Twist型のメッセージを使います7 class OutAndBack(): 8 def __init__(self):OutAndBackクラスを作ります
9 # Give the node a name
10 rospy.init_node('out_and_back', anonymous=False)
11
12 # Set rospy to execute a shutdown function when exiting
13 rospy.on_shutdown(self.shutdown)
out_and_backノードを初期化します。スクリプトが終了するときに呼ばれるコールバックon_shutdown()を宣言します。例えば、CtrlCtrl+cキーが押された時に呼ばれます。
15 # Publisher to control the robot's speed
16 self.cmd_vel = rospy.Publisher('/cmd_vel', Twist)
17
18 # How fast will we update the robot's movement?
19 rate = 50
20
21 # Set the equivalent ROS rate variable
22 r = rospy.Rate(rate)
/cmd_velトピックにTwist型の型のメッセージ(コマンド?)を送る宣言をします。
一秒間に50回のタイミングでコマンドをアップデートします。
24 # Set the forward linear speed to 0.2 meters per second
25 linear_speed = 0.2
26
27 # Set the travel distance to 1.0 meters
28 goal_distance = 1.0
29
30 # How long should it take us to get there?
31 linear_duration = linear_distance / linear_speed
ロボットの前進速度を秒速0.2メートルに設定します。
ゴールまでの距離を1.0メートルに設定します。
ゴールまでの到達時間を求めます。1.0/0.2=5秒
33 # Set the rotation speed to 1.0 radians per second
34 angular_speed = 1.0
35
36 # Set the rotation angle to Pi radians (180 degrees)
37 goal_angle = pi
38
39 # How long should it take to rotate?
40 angular_duration = angular_distance / angular_speed
この行は間違えなので、以下のように修正する。付属のスクリプトは正しい
40 angular_duration = goal_angle / angular_speed
同じように、ロボットの回転角速度を毎秒1.0ラジアンに設定し、
目標とする回転角度を180度(πラジアン)に設定すると、
目標とする回転角度までの時間は pi (3.14159263) / 1.0 = 3.14秒
42 # Loop through the two legs of the trip
43 for i in range(2):
44 # Initialize the movement command
45 move_cmd = Twist()
46
47 # Set the forward speed
48 move_cmd.linear.x = linear_speed
49
50 # Move forward for a time to go the desired distance
51 ticks = int(linear_duration * rate)
52
53 for t in range(ticks):
54 self.cmd_vel.publish(move_cmd)
55 r.sleep()
このループで実際にロボット動かします。一連の動きを2回繰り返します。
ロボットを1秒の間に、linear_speedの速度で、linear_distanceの距離だけ動かすために、1/rate 秒の間隔でTwist型のmove_cmd メッセージを出力し続けます。
r.sleep()では非常に短い時間(1/rate)だけスリープします。1/rateという時間は、r=rospy.Rate(rate)で設定された値になります。
57 # Stop the robot before the rotation 58 move_cmd = Twist() 59 self.cmd_vel.publish(move_cmd) 60 rospy.sleep(1)ここではループの後半に入る前に、ロボットを一旦停止させ、スクリプトを1秒間停止させます。
62 # Now rotate left roughly 180 degrees 63 64 # Set the angular speed 65 move_cmd.angular.z = angular_speed 66 67 # Rotate for a time to go 180 degrees 68 ticks = int(goal_angle * rate) 69 70 for t in range(ticks): 71 self.cmd_vel.publish(move_cmd) 72 r.sleep()ループの後半はロボットを回転させます。
1秒間で180度回転します。
74 # Stop the robot before the next leg
75 move_cmd = Twist()
76 self.cmd_vel.publish(move_cmd)
77 rospy.sleep(1)
2度めのループに入る前に、ロボットを一旦停止させ、スクリプトを1秒間停止させます。
79 # Stop the robot. 80 self.cmd_vel.publish(Twist())2度のループが終わったら、ロボットに空(すべてが0)のTwistメッセージ送る。
82 def shutdown(self):
83 # Always stop the robot when shutting down the node.
84 rospy.loginfo("Stopping the robot...")
85 self.cmd_vel.publish(Twist())
86 rospy.sleep(1)
何らかの理由でシャットダウン(Ctrl+cが押された)が実行された時はこのコールバック関数が実行される。
Tearminalウィンドウに”Stopping the robot..." が表示され、空のTwistメッセージが送られ、1秒間ループしたのちにスクリプトは終了する。
さて、timed_out_and_back.pyの動作をシミュレータで確認してみましょう。
$roslaunch rbx1_bringup fake_turtlebot.launch
$rosrun rviz rviz -d `rospack find rbx1_nav`/sim.rviz
$rosrun rbx1_nav timed_out_and_back.py
この3つのコマンドをそれぞれ別のTerminalウィンドウで実行して下さい。もう一つ別のウィンドウで $roscore を実行するのを忘れないでください。
0 件のコメント:
コメントを投稿