はじめに
前回の記事では、Navigation2 パッケージを用いて
- amcl パッケージで自己位置推定
- Path-Planning で経路計画
を実行しました。
今回の記事では、/cmd_vel を自作ロボットに転送できるようにします。
前提条件
前提条件は、以下の通りです。
- 前回までの記事が完了している
- Path-Planning が起動すると、/cmd_vel がパブリッシュされている
/cmd_vel の転送プログラムを作成
以前の記事ですが、こちらで translate_cmd_vel.py を作成したと思います。
translate_cmdvel.py を以下のように変更してください。
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
class cmdvel2Rover(Node):
    def __init__(self):
        # wake up node name
        super().__init__("Translate_cmdvel2_node")
        # declare publisher
        self.publisher = self.create_publisher(Twist, "/first_robot/cmd_vel", 40)
        # declare subscriber
        self.subscription = self.create_subscription(Twist, "/cmd_vel", self.get_scan_values, 40)
        # period publisher
        timer_period = 0.2
        self.timer = self.create_timer(timer_period, self.send_cmd_vel)
        # creating a message object to fit new velocities and publish them
        self.velocity = Twist()
        self.linear_x = 0.0
        self.linear_y = 0.0
        self.linear_z = 0.0
        self.angle_x = 0.0
        self.angle_y = 0.0
        self.angle_z = 0.0
    def get_scan_values(self, scan_data):
        # separate scan data
        self.linear_x = scan_data.linear.x
        self.linear_y = scan_data.linear.y
        self.linear_z = scan_data.linear.z
        self.angle_x = scan_data.angular.x
        self.angle_y = scan_data.angular.y
        self.angle_z = scan_data.angular.z
    def send_cmd_vel(self):
        # setting linear velocity
        self.velocity.linear.x = self.linear_x
        self.velocity.linear.y = self.linear_y
        self.velocity.linear.z = self.linear_z
        self.velocity.angular.x = -self.angle_x/2
       self.velocity.angular.y = -self.angle_y/2
        self.velocity.angular.z = -self.angle_z/2
        self.publisher.publish(self.velocity)
def main(args=None):
    rclpy.init(args=args)
    oab = cmdvel2Rover()
    rclpy.spin(oab)
    rclpy.shutdown()
if __name__ == "__main__":
    main()ここまできたら、説明しなくてもわかるかとは思いますが、説明しておきます。
# declare publisher
self.publisher = self.create_publisher(Twist, "/first_robot/cmd_vel", 40)
# declare subscriber
self.subscription = self.create_subscription(Twist, "/cmd_vel", self.get_scan_values, 40)
# period publisher
timer_period = 0.02
self.timer = self.create_timer(timer_period, self.send_cmd_vel)self.pubisher は、”/first_robot/cmd_vel” へパブリッシュするインスタンスです。
self.subscription は、 “/cmd_vel” をサブスクライブするインスタンスです。
一定時間ごとに self.get_scan_values 関数を起動します。
self.create_timer で 0.02s 毎に self.send_cmd_vel 関数を起動します。
def get_scan_values(self, scan_data):
    # separate scan data
    self.linear_x = scan_data.linear.x
    self.linear_y = scan_data.linear.y
    self.linear_z = scan_data.linear.z
    self.angle_x = scan_data.angular.x
    self.angle_y = scan_data.angular.y
    self.angle_z = scan_data.angular.z単純に、scan した Twist型のデータをTwist型の変数へ代入するのみです。
def send_cmd_vel(self):
    # setting linear velocity
    self.velocity.linear.x = self.linear_x
    self.velocity.linear.y = self.linear_y
    self.velocity.linear.z = self.linear_z
    self.velocity.angular.x = -self.angle_x/2
    self.velocity.angular.y = -self.angle_y/2
    self.velocity.angular.z = -self.angle_z/2
    self.publisher.publish(self.velocity)こちらも同様に、Twist型のデータを /first_robot/cmd_vel にパブリッシュします。
angle をなぜ負に反転させ、1/2 しているかは、実際に動かした時に説明します。
ここまでやってきてあれなのですが、凡ミスです。
translate_cmd_vel.py は既に setup.py に登録されているので、launch ファイルで同時起動できるようにしておきます。
first_navigation.launch.py を以下のように変更してください。
Node(
    package='rviz2',
    executable='rviz2',
    name='rviz2',
    arguments=['-d', rviz],
    parameters=[{'use_sim_time': use_sim_time}],
    output='screen'),
↓
Node(
    package='rviz2',
    executable='rviz2',
    name='rviz2',
    arguments=['-d', rviz],
    parameters=[{'use_sim_time': use_sim_time}],
    output='screen'),
Node(
    package='ros2_first_test',
    executable='translate_cmdvel',
    name='translate_cmdvel',
    output='screen'),これで完了です!
Path-Planning でロボットを動かしてみよう
ここまできたら、準備は完了です。
cd ~/ros_ws
colcon build --packages-select ros2_first_test
source ~/.bashrc
ros2 launch ros2_first_test first_navigation.launch.py自己位置推定は以下のGIFをご確認ください。
自己位置推定

ここで一つ問題があります。
amcl で推定されたロボット位置を拡大して確認してみます。

そうです。向きが逆です。
URDF の向きが違うので逆になっています。。。(凡ミスです。。。)
なので矢印の向きを逆にして 2D Pose Estimate を実行してください。
自律移動
上記の自己位置推定までを実行していただければ、以下のようにロボットが動くと思います。

そうなんです、バック走しています…。
自律走行後は、以下のようになっています。

完成です!
おわりに
今回は Navigation2 パッケージを用いて自律走行をシミュレートしました。
次回は、URDF ファイルと world ファイルを編集して、バック走ではなく前向きに走行するようにします。
 
  
  
  
  



コメント