見出し画像

Robotics and ROS 2 - Learn by Doing! Manipulators: タスクサーバー (セクション7-3/10)

  • MoveIt! 2 APIを使ったロボットの動作制御方法を学習し、C++とPythonでの実装を行った。

  • ROS 2アクションを利用してタスクサーバーを構築し、複数のタスク(ホーム、ピック、レスト)を実行できるようにした。

  • 最後に、Amazon Alexaと統合して音声コマンドでロボットを制御する実践的な応用を実現した。

「ロボティクスとROS 2 - 実践で学ぶマニピュレータ」コースのセクション7の最終3分の1に進むと、MoveIt! 2 APIの統合とロボティクスアプリケーションへの実用的な応用に焦点を当てます。このセグメントでは、MoveIt! 2 APIを使って新しいアプリケーションを開発し、ロボットの動きを制御するTask Serverを作成することに重点を置いています。以下にこれらの重要なレッスンについて詳しく説明します。

レッスン78:MoveIt! 2 APIの探索

このレッスンでは、MoveIt! 2 APIの詳細について、特にC++およびPythonインターフェースを通じた応用について学びます。このレッスンの核心は、グラフィカルインターフェースに依存せずに、コードを通じてロボットの動きを制御する方法を理解することです。

主要コンポーネント:

1. インターフェース作成:

  • C++を使用してロボットのアームとグリッパーのためのMoveIt! 2インターフェースを作成。

  • ロボットを特定の関節位置に移動させるサンプルコード。

void move_robot(const std::shared_ptr<rclcpp::Node> node) {
       auto arm_move_group = moveit::planning_interface::MoveGroupInterface(node, "arm");
       auto gripper_move_group = moveit::planning_interface::MoveGroupInterface(node, "gripper");

       std::vector<double> arm_joint_goal {1.57, 0.0, 0.0};
       std::vector<double> gripper_joint_goal {-0.7, 0.7};

       bool arm_within_bounds = arm_move_group.setJointValueTarget(arm_joint_goal);
       bool gripper_within_bounds = gripper_move_group.setJointValueTarget(gripper_joint_goal);

       if (!arm_within_bounds || !gripper_within_bounds) {
           RCLCPP_WARN(rclcpp::get_logger("rclcpp"),
                       "Target joint position(s) were outside of limits, but we will plan and clamp to the limits");
           return;
       }

       moveit::planning_interface::MoveGroupInterface::Plan arm_plan;
       moveit::planning_interface::MoveGroupInterface::Plan gripper_plan;
       bool arm_plan_success = (arm_move_group.plan(arm_plan) == moveit::core::MoveItErrorCode::SUCCESS);
       bool gripper_plan_success = (gripper_move_group.plan(gripper_plan) == moveit::core::MoveItErrorCode::SUCCESS);

       if(arm_plan_success && gripper_plan_success) {
           RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Planner SUCCEED, moving the arm and the gripper");
           arm_move_group.move();
           gripper_move_group.move();
       } else {
           RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "One or more planners failed!");
           return;
       }
}

2. 設定ファイル:

  • ロボットのSRDF(セマンティックロボット記述フォーマット)ファイルの詳細な設定、グループ、状態、および不要な衝突を無効にする設定。

レッスン79:C++でのMoveIt! 2 APIの実践

ここでは、MoveIt! 2 APIを使った実践的なコーディング演習を行います。ロボットの動きを制御するシンプルなC++スクリプトの作成に焦点を当てています。

ステップ:

1. インターフェースのコーディング:

  • MoveIt! 2とインターフェースするためのC++ノードの設定に関する詳細な指示。

  • パッケージのビルドのためのCMakeLists.txtの設定方法。

2. ビルドと実行:

  • colconを使用したパッケージのビルドと、適切なROS 2セットアップスクリプトを使った環境設定。

  • シミュレーションと制御ノードの起動、実装のテスト。

レッスン80:タスクサーバーの実装

このレッスンでは、ROS 2アクションを使用してタスクサーバーを作成します。これにより、受信する異なるゴールに基づいて複雑なロボット操作を実行できます。

主要コンポーネント:

1. タスクサーバーの設定:

  • 新しいROS 2パッケージ `arduinobot_remote` を作成し、タスクサーバーをホスト。

  • C++でタスクサーバーを実装し、ホームポジション、ピックポジション、レストポジションなどのタスクを処理。

void execute(const std::shared_ptr<rclcpp_action::ServerGoalHandle<arduinobot_msgs::action::ArduinobotTask>> goal_handle) {
       RCLCPP_INFO(get_logger(), "Executing goal");
       auto result = std::make_shared<arduinobot_msgs::action::ArduinobotTask::Result>();

       auto arm_move_group = moveit::planning_interface::MoveGroupInterface(shared_from_this(), "arm");
       auto gripper_move_group = moveit::planning_interface::MoveGroupInterface(shared_from_this(), "gripper");

       std::vector<double> arm_joint_goal;
       std::vector<double> gripper_joint_goal;

       if (goal_handle->get_goal()->task_number == 0) {
           arm_joint_goal = {0.0, 0.0, 0.0};
           gripper_joint_goal = {-0.7, 0.7};
       } else if (goal_handle->get_goal()->task_number == 1) {
           arm_joint_goal = {-1.14, -0.6, -0.07};
           gripper_joint_goal = {0.0, 0.0};
       } else if (goal_handle->get_goal()->task_number == 2) {
           arm_joint_goal = {-1.57, 0.0, -0.9};
           gripper_joint_goal = {0.0, 0.0};
       } else {
           RCLCPP_ERROR(get_logger(), "Invalid Task Number");
           return;
       }

       bool arm_within_bounds = arm_move_group.setJointValueTarget(arm_joint_goal);
       bool gripper_within_bounds = gripper_move_group.setJointValueTarget(gripper_joint_goal);
       if (!arm_within_bounds || !gripper_within_bounds) {
           RCLCPP_WARN(get_logger(),
                       "Target joint position(s) were outside of limits, but we will plan and clamp to the limits");
           return;
       }

       moveit::planning_interface::MoveGroupInterface::Plan arm_plan;
       moveit::planning_interface::MoveGroupInterface::Plan gripper_plan;
       bool arm_plan_success = (arm_move_group.plan(arm_plan) == moveit::core::MoveItErrorCode::SUCCESS);
       bool gripper_plan_success = (gripper_move_group.plan(gripper_plan) == moveit::core::MoveItErrorCode::SUCCESS);

       if(arm_plan_success && gripper_plan_success) {
           RCLCPP_INFO(get_logger(), "Planner SUCCEED, moving the arm and the gripper");
           arm_move_group.move();
           gripper_move_group.move();
       } else {
           RCLCPP_ERROR(get_logger(), "One or more planners failed!");
           return;
       }

       result->success = true;
       goal_handle->succeed(result);
       RCLCPP_INFO(get_logger(), "Goal succeeded");
}

2. タスクサーバーのテスト:

  • ROS 2アクションコマンドを使用してタスクサーバーにゴールを送信し、シミュレーション環境でロボットの応答を観察。

レッスン81:Amazon Alexaとの統合による音声制御アクション

この最後のレッスンでは、Amazon Alexaを使用して音声コマンドでロボットを制御するエキサイティングな可能性を探ります。このレッスンでは、ROS 2とMoveIt! 2の多様な要素を組み合わせ、実際の応用例を示しています。

ステップ:

1. 音声コマンドの設定:

  • タスクサーバーをAmazon Alexaと統合し、音声コマンドを受け取ってロボットの動きを実行。

  • Alexaとインターフェースし、対応するタスクをタスクサーバーに送信するPythonスクリプトの作成。

2. 実践的な応用:

  • 音声コマンド機能をテストし、異なるタスクをロボットに送信してリアルタイムでその動きを観察。

結論

セクション7の最終3分の1では、MoveIt! 2 APIの理解を深めるだけでなく、それをロボティクスの実際の応用に活かす方法を示しています。タスクサーバーを実装し、音声コマンドを統合することで、私たちのロボットシステムとの新たなインタラクションの次元が開かれました。この実践的なアプローチにより、複雑なロボットアプリケーションを開発するスキルが身に付き、自動化やそれを超えた革新的なソリューションへの道が開かれました。開かれました。

「超本当にドラゴン」へ


この記事が気に入ったらサポートをしてみませんか?