Skill list_motions
Version: 1.0.0
Default path:
/skill/list_motionsDatatype: motion_skills_action_ListMotions.srv
Definition source:
package.xmlin ros4hri/motions_skills
List the available pre-recorded motions that can be executed with the replay_motion skill.
Input parameters
Output fields
motions
array of stringThe list of available motion names that can be executed with the replay_motion skill.
Quick snippets
Call the skill from the command-line
$ ros2 service call /skill/list_motions motion_skills/action/ListMotions.srv # then press Tab to complete the message prototype
Call the action from a Python script:
Call the action from a C++ program:
#include <functional>
#include <future>
#include <memory>
#include <string>
#include <sstream>
#include <chrono>
#include "motion_skills/action/.hpp"
#include "rclcpp/rclcpp.hpp"
#include "rclcpp_action/rclcpp_hpp"
#include "rclcpp_components/register_node_macro.hpp"
using namespace std::chrono_literals;
using namespace std;
class Listmotions.srvActionClient : public rclcpp::Node
{
public:
using = motion_skills::action::;
using GoalHandle = rclcpp_action::ClientGoalHandle<>;
explicit Listmotions.srvActionClient(const rclcpp::NodeOptions & options)
: Node("list_motions_action_client", options)
{
this->client_ptr_ = rclcpp_action::create_client<>(
this,
"");
this->timer_ = this->create_wall_timer(
500ms,
bind(&Listmotions.srvActionClient::send_goal, this));
}
void send_goal()
{
using namespace std::placeholders;
this->timer_->cancel();
if (!this->client_ptr_->wait_for_action_server()) {
RCLCPP_ERROR(this->get_logger(), "Action server not available after waiting");
rclcpp::shutdown();
}
auto goal_msg = ::Goal();
// check the ListMotions.srvGoal message
// definition for the possible goal parameters
// goal_msg.... = ...;
RCLCPP_INFO(this->get_logger(), "Sending goal");
auto send_goal_options = rclcpp_action::Client<>::SendGoalOptions();
send_goal_options.goal_response_callback =
bind(&Listmotions.srvActionClient::goal_response_callback, this, _1);
send_goal_options.feedback_callback =
bind(&Listmotions.srvActionClient::feedback_callback, this, _1, _2);
send_goal_options.result_callback =
bind(&Listmotions.srvActionClient::result_callback, this, _1);
this->client_ptr_->async_send_goal(goal_msg, send_goal_options);
}
private:
rclcpp_action::Client<>::SharedPtr client_ptr_;
rclcpp::TimerBase::SharedPtr timer_;
void goal_response_callback(const GoalHandle::SharedPtr & goal_handle)
{
if (!goal_handle) {
RCLCPP_ERROR(this->get_logger(), "Goal was rejected by server");
} else {
RCLCPP_INFO(this->get_logger(), "Goal accepted by server, waiting for result");
}
}
void feedback_callback(
GoalHandle::SharedPtr,
const shared_ptr<const ::Feedback> feedback)
{
stringstream ss;
ss << "Next number in sequence received: ";
for (auto number : feedback->partial_sequence) {
ss << number << " ";
}
RCLCPP_INFO(this->get_logger(), ss.str().c_str());
}
void result_callback(const GoalHandle::WrappedResult & result)
{
switch (result.code) {
case rclcpp_action::ResultCode::SUCCEEDED:
break;
case rclcpp_action::ResultCode::ABORTED:
RCLCPP_ERROR(this->get_logger(), "Goal was aborted");
return;
case rclcpp_action::ResultCode::CANCELED:
RCLCPP_ERROR(this->get_logger(), "Goal was canceled");
return;
default:
RCLCPP_ERROR(this->get_logger(), "Unknown result code");
return;
}
stringstream ss;
ss << "Result received: ";
for (auto number : result.result->sequence) {
ss << number << " ";
}
RCLCPP_INFO(this->get_logger(), ss.str().c_str());
rclcpp::shutdown();
}
}; // class Listmotions.srvActionClient
RCLCPP_COMPONENTS_REGISTER_NODE(Listmotions.srvActionClient)
You can call this skill from QML using the following code snippet. See ros_qml_plugin to learn more.
import Ros 2.0
// ...
ListMotionsSkill {
id: mySkill
onResult: {
console.log("Skill result: " + result);
}
}
// Call the skill
mySkill.list_motions();
See also
List of other Motions skills