Teaching Assistant: Roi Yehoshua

Slides:



Advertisements
Similar presentations
Chapter 6 Server-side Programming: Java Servlets
Advertisements

Practical techniques & Examples
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Sonar and Localization LMICSE Workshop June , 2005 Alma College.
Teaching Assistant: Roi Yehoshua
1 Configuring Internet- related services (April 22, 2015) © Abdou Illia, Spring 2015.
Reference: / MPI Program Structure.
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Client Server Model The client machine (or the client process) makes the request for some resource or service, and the server machine (the server process)
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
C++ Functions. 2 Agenda What is a function? What is a function? Types of C++ functions: Types of C++ functions: Standard functions Standard functions.
Web Proxy Server. Proxy Server Introduction Returns status and error messages. Handles http CGI requests. –For more information about CGI please refer.
Teaching Assistant: Roi Yehoshua
Chapter 4: Threads Adapted to COP4610 by Robert van Engelen.
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
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
Copyright © 2007, Oracle. All rights reserved. Managing Concurrent Requests.
A First Book of C++: From Here To There, Third Edition2 Objectives You should be able to describe: Function and Parameter Declarations Returning a Single.
LiveCycle Data Services Introduction Part 2. Part 2? This is the second in our series on LiveCycle Data Services. If you missed our first presentation,
Autonomous Robot Project Lauren Mitchell Ashley Francis.
Teaching Assistant: Roi Yehoshua
The Generic Gaming Engine Andrew Burke Advisor: Prof. Aaron Cass Abstract Games have long been a source of fascination. Their inherent complexity has challenged.
CSE 332: C++ debugging in Eclipse C++ Debugging in Eclipse We’ve now covered several key program features –Variable declarations, expressions and statements.
Running Servlets JSDK2.1 default.cfg : Web Server configuration information batch files to start and stop server Servlet properties in /webpages/WEB-INF.
Execute Workflow. Home page To execute a workflow navigate to My Workflows Page.
Teaching Assistant: Roi Yehoshua
Code reading skills LEVEL GAME.  Skeleton has error messages.  Notice the red lines on right slider. Click… you’ll go to an error.  pieces = levels.getPieces();
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
Data Display Debugger (DDD)
Fall 2002 CS 325 Class Notes Page 1 Lecture 25 Today –exec() in Unix –CreateProcess in Windows Announcements.
M1G Introduction to Programming 2 3. Creating Classes: Room and Item.
Teaching Assistant: Roi Yehoshua
Lecture 4 Mechanisms & Kernel for NOSs. Mechanisms for Network Operating Systems  Network operating systems provide three basic mechanisms that support.
Basic ActionScript and PHP Cis 126. Getting Started set up a basic folder structure so we can keep our files organized. Mirror this structure on your.
Teaching Assistant: Roi Yehoshua
Subscribers – List Model
Advanced Task Engine Doing Cool Stuff with Cool stuff!
CS241 Systems Programming Discussion Section Week 2 Original slides by: Stephen Kloder.
C++ Functions A bit of review (things we’ve covered so far)
Lecturer: Roi Yehoshua
Lecturer: Roi Yehoshua
Lecturer: Roi Yehoshua
Lecturer: Roi Yehoshua
Principles of Software Development
Lecturer: Roi Yehoshua
What is ROS? ROS is an open-source robot operating system
Multi-Robot Systems with ROS Lesson 2
- The Robot Operating System
Mixed Reality Server under Robot Operating System
Quick Introduction to ROS
Robotics and Perception
Robotic Perception and Action
Robotic Perception and Action
Java IDE Dwight Deugo Nesa Matic Portions of the notes for this lecture include excerpts from.
Robotic Perception and Action
Robot Operating System (ROS): An Introduction
Presentation transcript:

Teaching Assistant: Roi Yehoshua

Adaptive Monte-Carlo Localization actionlib Sending goals from code Making navigation plans (C)2014 Roi Yehoshua

Localization is the problem of estimating the pose of the robot relative to a map Localization is not terribly sensitive to the exact placement of objects so it can handle small changes to the locations of objects ROS uses the amcl package for localization (C)2014 Roi Yehoshua

amcl is a probabilistic localization system for a robot moving in 2D It implements the adaptive Monte Carlo localization approach, which uses a particle filter to track the pose of a robot against a known map The algorithm and its parameters are described in the book Probabilistic Robotics by Thrun, Burgard, and Fox ( Currently amcl works only with laser scans and laser maps. However, it can be extended to work with other sensor data. (C)2014 Roi Yehoshua

amcl takes in a laser-based map, laser scans, and transform messages, and outputs pose estimates Subscribed topics: – scan – Laser scans – tf – Transforms – initialpose – Mean and covariance with which to (re-) initialize the particle filter – map – the map used for laser-based localization Published topics: – amcl_pose – Robot's estimated pose in the map, with covariance. – Particlecloud – The set of pose estimates being maintained by the filter (C)2014 Roi Yehoshua

DefaultDescriptionParameter 100Minimum allowed number of particlesmin_particles 5000Maximum allowed number of particlesmax_particles likelihood_fieldWhich model to use, either beam or likelihood_fieldlaser_model_type 2.0Maximum distance to do obstacle inflation on map, for use in likelihood_field model laser_likelihood_ max_dist 0.0Initial pose mean (x), used to initialize filter with Gaussian distribution initial_pose_x 0.0Initial pose mean (y), used to initialize filter with Gaussian distribution initial_pose_y 0.0Initial pose mean (yaw), used to initialize filter with Gaussian distribution initial_pose_a

(C)2014 Roi Yehoshua <!-- Example amcl configuration. Descriptions of parameters, as well as a full list of all amcl parameters, can be found at --> <!-- Example amcl configuration. Descriptions of parameters, as well as a full list of all amcl parameters, can be found at -->

(C)2014 Roi Yehoshua --> -->

To run the navigation stack with amcl, you need to run the following nodes: – map_server – for loading the map – stageros – for the Stage simulator – amcl – for the localization system – move_base – manages the navigation stack (C)2014 Roi Yehoshua

To run this launch file type: $ roscd navigation_stage/launch $ roslaunch move_base_amcl_5cm.launch $ roscd navigation_stage/launch $ roslaunch move_base_amcl_5cm.launch

The navigation stack waits for the new pose by listening to the topic initialpose The 2D Pose Estimate button (P shortcut) allows the user to initialize the localization system by setting the pose of the robot in the world Click on the button and then click on the map to indicate the initial position of your robot – Make sure that the Fixed Frame is set to "map” If you don't do this at the beginning, the robot will try to auto-localize itself (C)2014 Roi Yehoshua

The Particle Cloud display shows the particle cloud used by the robot's localization system The spread of the cloud represents the localization system's uncertainty about the robot's pose – A cloud that spreads out a lot reflects high uncertainty, while a condensed cloud represents low uncertainty – As the robot moves about the environment, this cloud should shrink in size as additional scan data allows amcl to refine its estimate of the robot's position and orientation (C)2014 Roi Yehoshua

To watch the particle cloud in rviz: – Click Add Display and choose Pose Array – Set topic name to /particlecloud (C)2014 Roi Yehoshua

Taken from ROS by Example / Goebel

The actionlib stack provides a standardized interface for interfacing with tasks including: – Sending goals to the robot – Performing a laser scan – Detecting the handle of a door Provides abilities that services don’t have: – cancel a long-running task during the execution – get periodic feedback about how the request is progressing (C)2014 Roi Yehoshua

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)2014 Roi Yehoshua

The action specification is defined using a.action file. These files are placed in a package’s./action directory Example: (C)2014 Roi Yehoshua

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)2014 Roi Yehoshua

The next code is a simple example to send a goal to move the robot In this case the goal would be a PoseStamped message that contains information about where the robot should move to in the world pleGoals pleGoals (C)2014 Roi Yehoshua

First create a new package called send_goals This package depends on the following packages: – actionlib – geometry_msgs – move_base_msgs (C)2014 Roi Yehoshua $ cd ~/catkin_ws/src $ catkin_create_pkg send_goals std_msgs rospy roscpp actionlib tf geometry_msgs move_base_msgs $ catkin_make --force-cmake -G"Eclipse CDT4 - Unix Makefiles" $ cd ~/catkin_ws/src $ catkin_create_pkg send_goals std_msgs rospy roscpp actionlib tf geometry_msgs move_base_msgs $ catkin_make --force-cmake -G"Eclipse CDT4 - Unix Makefiles"

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

#include typedef actionlib::SimpleActionClient MoveBaseClient; int main(int argc, char** argv) { ros::init(argc, argv, "send_goals_node"); // create the action client // true causes the client to spin its own thread 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"); #include typedef actionlib::SimpleActionClient MoveBaseClient; int main(int argc, char** argv) { ros::init(argc, argv, "send_goals_node"); // create the action client // true causes the client to spin its own thread 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)2014 Roi Yehoshua // 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 = ; goal.target_pose.pose.position.y = ; goal.target_pose.pose.orientation.w = 1; ROS_INFO("Sending goal"); ac.sendGoal(goal); // 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; } // 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 = ; goal.target_pose.pose.position.y = ; goal.target_pose.pose.orientation.w = 1; ROS_INFO("Sending goal"); ac.sendGoal(goal); // 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; }

Add the following lines to CMakeLists.txt: Call catkin_make (C)2014 Roi Yehoshua add_executable(send_goals_node src/SendGoals.cpp) target_link_libraries(send_goals_node ${catkin_LIBRARIES} ) add_executable(send_goals_node src/SendGoals.cpp) target_link_libraries(send_goals_node ${catkin_LIBRARIES} )

First run the navigation stack: Set the initial pose of the robot in rviz Then run send_goals_node: (C)2014 Roi Yehoshua cd ~/ros/stacks/navigation_tutorials/navigation_stage/launch roslaunch move_base_amcl_5cm.launch cd ~/ros/stacks/navigation_tutorials/navigation_stage/launch roslaunch move_base_amcl_5cm.launch rosrun send_goals send_goals_node

(C)2014 Roi Yehoshua

The graph shows that the client is subscribing to the status channel of move_base and publishing to the goal channel as expected (C)2014 Roi Yehoshua

Now let’s specify the desired orientation of the robot in the final pose as 90 degrees It will be easier to define it with Euler angles and convert it to a quaternion message: (C)2014 Roi Yehoshua 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; 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)2014 Roi Yehoshua

Now let us make the desired pose of the robot configurable in a launch file, so we can send different goals to the robot from the terminal You can set a parameter using the tag in the ROS launch file: (C)2014 Roi Yehoshua

There are two methods to retrieve parameters with a NodeHandle: – getParam(key, output_value) – param() is similar to getParam(), but allows you to specify a default value in the case that the parameter could not be retrieved Example: (C)2014 Roi Yehoshua // Read x, y and angle params ros::NodeHandle nh; double x, y, theta; nh.getParam("goal_x", x); nh.getParam("goal_y", y); nh.getParam("goal_theta", theta); // Read x, y and angle params ros::NodeHandle nh; double x, y, theta; nh.getParam("goal_x", x); nh.getParam("goal_y", y); nh.getParam("goal_theta", theta);

Use the tag to define a parameter list: Example of accessing the list in the code: (C)2014 Roi Yehoshua [1, 2, 3, 4] std::vector my_list; int sum = 0; nh.getParam("my_list", my_list); for(unsigned i = 0; i < my_list.size(); i++) { sum += my_list[i]; } std::vector my_list; int sum = 0; nh.getParam("my_list", my_list); for(unsigned i = 0; i < my_list.size(); i++) { sum += my_list[i]; }

Copy the following directories and files from the navigation_tutorials stack to the launch directory of your package: (C)2014 Roi Yehoshua

move_base_config files: (C)2014 Roi Yehoshua

stage_config files: (C)2014 Roi Yehoshua

Fix move_base.xml to use the correct package name: (C)2014 Roi Yehoshua

Set the robot’s initial pose in amcl_node.xml: (C)2014 Roi Yehoshua

Fix the single_robot.rviz file – Change topic name for the robot footprint (C)2014 Roi Yehoshua

Edit the send_goals.launch file: (C)2014 Roi Yehoshua

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 (C)2014 Roi Yehoshua $ roslaunch send_goals send_goals.launch

(C)2014 Roi Yehoshua

Allows an external user to ask for a plan to a given pose from move_base without causing move_base to execute that plan Arguments: – Start pose – Goal pose – Goal tolerance Returns: – a message of type nav_msgs/GetPlannav_msgs/GetPlan (C)2014 Roi Yehoshua

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 Create a new C++ file called MakePlan.cpp (C)2014 Roi Yehoshua

#include #include using std::string; #include #define forEach BOOST_FOREACH double g_GoalTolerance = 0.5; string g_WorldFrame = "map"; void fillPathRequest(nav_msgs::GetPlan::Request &req); void callPlanningService(ros::ServiceClient &serviceClient, nav_msgs::GetPlan &srv); #include #include using std::string; #include #define forEach BOOST_FOREACH double g_GoalTolerance = 0.5; string g_WorldFrame = "map"; void fillPathRequest(nav_msgs::GetPlan::Request &req); void callPlanningService(ros::ServiceClient &serviceClient, nav_msgs::GetPlan &srv);

(C)2014 Roi Yehoshua 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_node/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 (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); if (!serviceClient) { ROS_FATAL("Persistent service connection to %s failed", serviceClient.getService().c_str()); return -1; } callPlanningService(serviceClient, srv); } 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_node/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 (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); if (!serviceClient) { ROS_FATAL("Persistent service connection to %s failed", serviceClient.getService().c_str()); return -1; } callPlanningService(serviceClient, srv); }

(C)2014 Roi Yehoshua void fillPathRequest(nav_msgs::GetPlan::Request &request) { request.start.header.frame_id = g_WorldFrame; request.start.pose.position.x = ; request.start.pose.position.y = ; request.start.pose.orientation.w = 1.0; request.goal.header.frame_id = g_WorldFrame; request.goal.pose.position.x = ; request.goal.pose.position.y = ; request.goal.pose.orientation.w = 1.0; request.tolerance = g_GoalTolerance; } void fillPathRequest(nav_msgs::GetPlan::Request &request) { request.start.header.frame_id = g_WorldFrame; request.start.pose.position.x = ; request.start.pose.position.y = ; request.start.pose.orientation.w = 1.0; request.goal.header.frame_id = g_WorldFrame; request.goal.pose.position.x = ; request.goal.pose.position.y = ; request.goal.pose.orientation.w = 1.0; request.tolerance = g_GoalTolerance; }

(C)2014 Roi Yehoshua 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"); } else { ROS_ERROR("Failed to call service %s - is the robot moving?", serviceClient.getService().c_str()); } 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"); } else { ROS_ERROR("Failed to call service %s - is the robot moving?", serviceClient.getService().c_str()); }

(C)2014 Roi Yehoshua

Create a patrol bot program Read assignment details at 685/assignment2/assignment2.html 685/assignment2/assignment2.html (C)2014 Roi Yehoshua