Lecturer: Roi Yehoshua

Slides:



Advertisements
Similar presentations
Generalized Requests. The current definition They are defined in MPI 2 under the hood of the chapter 8 (External Interfaces) Page 166 line 16 The objective.
Advertisements

Teaching Assistant: Roi Yehoshua
Using Eclipse. Getting Started There are three ways to create a Java project: 1:Select File > New > Project, 2 Select the arrow of the button in the upper.
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
CGI Programming Languages Web Based Software Development July 21, 2005 Song, JaeHa.
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Multi-Robot Systems with ROS Lesson 1
What is ROS? Robot Operating System
Grail Interface and Code Ramón Creager. What is Grail? Like the Roman god Janus, Grail provides two faces to two different worlds: From the outside, a.
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Chapter 4: Threads. 4.2 Silberschatz, Galvin and Gagne ©2005 Operating System Concepts Threads A thread (or lightweight process) is a basic unit of CPU.
Teaching Assistant: Roi Yehoshua
CS4273: Distributed System Technologies and Programming I Lecture 7: Java Networking.
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
1 Cisco Unified Application Environment Developers Conference 2008© 2008 Cisco Systems, Inc. All rights reserved.Cisco Public Introduction to Etch Scott.
Chapter 10 Defining Classes. The Internal Structure of Classes and Objects Object – collection of data and operations, in which the data can be accessed.
Chapter 6 Introduction to Defining Classes. Objectives: Design and implement a simple class from user requirements. Organize a program in terms of a view.
Teaching Assistant: Roi Yehoshua
Silberschatz, Galvin and Gagne  2002 Modified for CSCI 399, Royden, Operating System Concepts Operating Systems Lecture 14 Threads 2 Read Ch.
A brief introduction to javadoc and doxygen. What’s in a program file? 1. Comments 2. Code.
Philip Repsher October 29 th, 2008 Or Maybe November 3 rd, 2008.
Desktop Integration with the Appx Client. Launch Documents Run Desktop Programs Transfer Files to the Client Transfer Files from the Client Client-Side.
Teaching Assistant: Roi Yehoshua
CSC 520 – Advanced Object Oriented Programming, Fall, 2010 Thursday, October 14 Week 7, UML Diagrams
Teaching Assistant: Roi Yehoshua
USING ANDROID WITH THE INTERNET. Slide 2 Lecture Summary Getting network permissions Working with the HTTP protocol Sending HTTP requests Getting results.
Lecturer: Roi Yehoshua
Lecturer: Roi Yehoshua
Lecturer: Roi Yehoshua
Lecturer: Roi Yehoshua
Principles of Software Development
Lecturer: Roi Yehoshua
Lecturer: Roi Yehoshua
Lecturer: Roi Yehoshua
Lecture 7: Android Services
Chapter 5 Remote Procedure Call
Data Transport for Online & Offline Processing
Introduction to writing and debugging micro-services
Chapter 4: Threads.
What is ROS? ROS is an open-source robot operating system
#01 Client/Server Computing
Multi-Robot Systems with ROS Lesson 10
Multi-Robot Systems with ROS Lesson 2
- The Robot Operating System
Mixed Reality Server under Robot Operating System
Processes Chapter 3.
Exploring the Power of EPDM Tasks - Working with and Developing Tasks in EPDM By: Marc Young XLM Solutions
Quick Introduction to ROS
Introduction to javadoc
Robotics and Perception
Robotic Perception and Action
Robotic Perception and Action
Processes Chapter 3.
Processes Chapter 3.
Robotic Perception and Action
Outline Chapter 3: Processes Chapter 4: Threads So far - Next -
Robot Operating System (ROS): An Introduction
#01 Client/Server Computing
Presentation transcript:

Lecturer: Roi Yehoshua roiyeho@gmail.com October 2016 ROS – Lecture 8 ROS actions Sending goal commands from code Making navigation plans Lecturer: Roi Yehoshua roiyeho@gmail.com

Actions http://wiki.ros.org/actionlib While services are handy for simple get/set interactions like querying status and managing configuration, they don’t work well with long-running tasks such as sending a robot to some distant location ROS actions are the best way to implement interfaces to time-extended, goal-oriented behaviors Similar to the request and response of a service, an action uses a goal to initiate a behavior and sends a result when the behavior is complete But the action further uses feedback to provide updates on the behavior’s progress toward the goal and also allows for goals to be canceled Actions are asynchronous (in contrast to services) (C)2016 Roi Yehoshua

Action Client-Server Interaction (C)2016 Roi Yehoshua

Action Server State Transitions (C)2016 Roi Yehoshua

Action Client State Transitions (C)2016 Roi Yehoshua

.action File The action specification is defined in an .action file These files are placed in the package’s ./action directory Example for an action file: (C)2016 Roi Yehoshua

.action File From the action file the following message types are generated: DoDishesAction.msg DoDishesActionGoal.msg DoDishesActionResult.msg DoDishesActionFeedback.msg DoDishesGoal.msg DoDishesResult.msg DoDishesFeedback.msg These messages are then used internally by actionlib to communicate between the ActionClient and ActionServer (C)2016 Roi Yehoshua

SimpleActionClient A simple client implementation which supports only one goal at a time The action client is templated on the action definition, specifying what message types to communicate to the action server with The action client c’tor also takes two arguments: The server name to connect to A boolean option to automatically spin a thread If you prefer not to use threads (and you want actionlib to do the 'thread magic' behind the scenes), this is a good option for you. (C)2016 Roi Yehoshua

SimpleActionClient (C)2016 Roi Yehoshua

SendGoals The next code is a simple example to send a goal to move the robot from the C++ code In this case the goal would be a PoseStamped message that contains information about where the robot should move to in the world http://wiki.ros.org/navigation/Tutorials/SendingSimpleGoals (C)2016 Roi Yehoshua

SendGoals First create a new package called send_goals This package depends on the following packages: actionlib geometry_msgs move_base_msgs $ cd ~/catkin_ws/src $ catkin_create_pkg send_goals std_msgs rospy roscpp actionlib tf geometry_msgs move_base_msgs (C)2016 Roi Yehoshua

SendGoals Open the project file in Eclipse Under the src subdirectory, create a new file called SendGoals.cpp (C)2016 Roi Yehoshua

SendGoals.cpp (1) #include <ros/ros.h> #include <move_base_msgs/MoveBaseAction.h> #include <actionlib/client/simple_action_client.h> #include <tf/transform_datatypes.h> typedef actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction> MoveBaseClient; int main(int argc, char** argv) { ros::init(argc, argv, "send_goals_node"); // Get the goal's x, y and angle from the launch file double x, y, theta; ros::NodeHandle nh; nh.getParam("goal_x", x); nh.getParam("goal_y", y); nh.getParam("goal_theta", theta); // create the action client MoveBaseClient ac("move_base", true); // Wait 60 seconds for the action server to become available ROS_INFO("Waiting for the move_base action server"); ac.waitForServer(ros::Duration(60)); ROS_INFO("Connected to move base server"); (C)2016 Roi Yehoshua

SendGoals.cpp (2) // Send a goal to move_base move_base_msgs::MoveBaseGoal goal; goal.target_pose.header.frame_id = "map"; goal.target_pose.header.stamp = ros::Time::now();   goal.target_pose.pose.position.x = x; goal.target_pose.pose.position.y = y; // Convert the Euler angle to quaternion double radians = theta * (M_PI/180); tf::Quaternion quaternion; quaternion = tf::createQuaternionFromYaw(radians); geometry_msgs::Quaternion qMsg; tf::quaternionTFToMsg(quaternion, qMsg); goal.target_pose.pose.orientation = qMsg; // Send the goal command ROS_INFO("Sending robot to: x = %f, y = %f, theta = %f", x, y, theta); ac.sendGoal(goal);  (C)2016 Roi Yehoshua

SendGoals.cpp (3) // Wait for the action to return ac.waitForResult();   if (ac.getState() == actionlib::SimpleClientGoalState::SUCCEEDED) ROS_INFO("You have reached the goal!"); else ROS_INFO("The base failed for some reason"); return 0; } (C)2016 Roi Yehoshua

Converting Euler Angle to Quaternion It is easier to define the goal pose with Euler angles rather than with quaternions The following code translates the angle from radians to quaternion representation: double theta = 90.0; double radians = theta * (M_PI/180); tf::Quaternion quaternion; quaternion = tf::createQuaternionFromYaw(radians); geometry_msgs::Quaternion qMsg; tf::quaternionTFToMsg(quaternion, qMsg); goal.target_pose.pose.orientation = qMsg; (C)2016 Roi Yehoshua

SendGoals Launch File <launch> <param name="goal_x" value="2" /> <param name="goal_y" value="-2" /> <param name="goal_theta" value="180" /> <param name="/use_sim_time" value="true"/> <!-- Launch turtle bot world --> <include file="$(find turtlebot_gazebo)/launch/turtlebot_world.launch"/> <!-- Launch navigation stack with amcl --> <include file="$(find turtlebot_gazebo)/launch/amcl_demo.launch"/> <!-- Launch rviz --> <include file="$(find turtlebot_rviz_launchers)/launch/view_navigation.launch"/> <!-- Launch send goals node --> <node name="send_goals_node" pkg="send_goals" type="send_goals_node" output="screen"/> </launch> (C)2016 Roi Yehoshua

SendGoals Demo Launch send_goals.launch: You should now see rviz opens and the robot moves from its initial pose to the target pose defined in the launch file $ roslaunch send_goals send_goals.launch (C)2016 Roi Yehoshua

SendGoals Demo (C)2016 Roi Yehoshua

SendGoals Demo (C)2016 Roi Yehoshua

SendGoals Demo (C)2016 Roi Yehoshua

Nodes Graph (C)2016 Roi Yehoshua

make_plan service Allows an external user to ask from move_base a route to a given pose without actually moving the robot Arguments: Start pose Goal pose Goal tolerance Returns a message of type nav_msgs/GetPlan (C)2016 Roi Yehoshua

make_plan Node In our send_goal package we will now create a make_plan_node that will call the make_plan service and print the output path of the plan Add a new C++ file called MakePlan.cpp (C)2016 Roi Yehoshua

MakePlan.cpp (1) #include <ros/ros.h> #include <nav_msgs/GetPlan.h> #include <geometry_msgs/PoseStamped.h>   #include <string> using std::string; #include <boost/foreach.hpp> #define forEach BOOST_FOREACH double goalTolerance = 0.5; void fillPathRequest(nav_msgs::GetPlan::Request &req); void callPlanningService(ros::ServiceClient &serviceClient, nav_msgs::GetPlan &srv); (C)2016 Roi Yehoshua

MakePlan.cpp (2) int main(int argc, char** argv) { ros::init(argc, argv, "make_plan_node"); ros::NodeHandle nh;   // Init service query for make plan string service_name = "move_base/make_plan"; while (!ros::service::waitForService(service_name, ros::Duration(3.0))) { ROS_INFO("Waiting for service move_base/make_plan to become available"); } ros::ServiceClient serviceClient = nh.serviceClient<nav_msgs::GetPlan>(service_name, true); if (!serviceClient) { ROS_FATAL("Could not initialize get plan service from %s", serviceClient.getService().c_str()); return -1; nav_msgs::GetPlan srv; fillPathRequest(srv.request);  ROS_FATAL("Persistent service connection to %s failed", serviceClient.getService().c_str()); }  callPlanningService(serviceClient, srv); (C)2016 Roi Yehoshua

MakePlan.cpp (3) void fillPathRequest(nav_msgs::GetPlan::Request &request) { request.start.header.frame_id = "map"; request.start.pose.position.x = 0; request.start.pose.position.y = 0; request.start.pose.orientation.w = 1.0;   request.goal.header.frame_id = "map"; request.goal.pose.position.x = 2.0; request.goal.pose.position.y = -2.0; request.goal.pose.orientation.w = 1.0; request.tolerance = goalTolerance; } (C)2016 Roi Yehoshua

MakePlan.cpp (4) void callPlanningService(ros::ServiceClient &serviceClient, nav_msgs::GetPlan &srv) { // Perform the actual path planner call if (serviceClient.call(srv)) {  if (!srv.response.plan.poses.empty()) { forEach(const geometry_msgs::PoseStamped &p, srv.response.plan.poses) { ROS_INFO("x = %f, y = %f", p.pose.position.x, p.pose.position.y); } else { ROS_WARN("Got empty plan"); ROS_ERROR("Failed to call service %s - is the robot moving?", serviceClient.getService().c_str()); (C)2016 Roi Yehoshua

make_plan.launch <launch> <param name="goal_x" value="2" /> <param name="goal_y" value="-2" /> <param name="goal_theta" value="180" /> <param name="/use_sim_time" value="true"/> <!-- Launch turtle bot world --> <include file="$(find turtlebot_gazebo)/launch/turtlebot_world.launch"/> <!-- Launch navigation stack with amcl --> <include file="$(find turtlebot_gazebo)/launch/amcl_demo.launch"/> <!-- Launch send goals node --> <node name="make_plan_node" pkg="send_goals" type="make_plan_node" output="screen"/> </launch> (C)2016 Roi Yehoshua

Running make_plan Node (C)2016 Roi Yehoshua