From ae9f618a97bf3fff465b678a6bd40e376ceed53d Mon Sep 17 00:00:00 2001 From: fsuarez6 Date: Tue, 22 Apr 2014 17:03:11 +0200 Subject: [PATCH] Added scoring interface (topics and services) --- labrob_control/CHANGELOG.rst | 5 + labrob_description/CHANGELOG.rst | 5 + labrob_gazebo/CHANGELOG.rst | 5 + labrob_msgs/CHANGELOG.rst | 8 ++ labrob_msgs/CMakeLists.txt | 23 ++++ labrob_msgs/package.xml | 22 ++++ labrob_msgs/srv/GetMapPercentage.srv | 3 + labrob_worlds/CHANGELOG.rst | 8 ++ labrob_worlds/CMakeLists.txt | 6 ++ labrob_worlds/launch/crazy_maze.launch | 17 ++- labrob_worlds/models/crazy_coins/model.sdf | 2 + labrob_worlds/package.xml | 6 +- labrob_worlds/scripts/challenge_map_server.py | 34 ++++++ labrob_worlds/setup.py | 11 ++ labrob_worlds/src/coins_manager_plugin.cpp | 102 +++++++++++++----- 15 files changed, 216 insertions(+), 41 deletions(-) create mode 100644 labrob_msgs/CHANGELOG.rst create mode 100644 labrob_msgs/CMakeLists.txt create mode 100644 labrob_msgs/package.xml create mode 100644 labrob_msgs/srv/GetMapPercentage.srv create mode 100644 labrob_worlds/CHANGELOG.rst create mode 100755 labrob_worlds/scripts/challenge_map_server.py create mode 100644 labrob_worlds/setup.py diff --git a/labrob_control/CHANGELOG.rst b/labrob_control/CHANGELOG.rst index 324638e..529aa13 100644 --- a/labrob_control/CHANGELOG.rst +++ b/labrob_control/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package labrob_control ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Added scoring interface (topics and services) +* Contributors: Alex, fsuarez6 + 0.1.0 (2014-04-07) ------------------ * Initial release diff --git a/labrob_description/CHANGELOG.rst b/labrob_description/CHANGELOG.rst index a214d82..60ca1a7 100644 --- a/labrob_description/CHANGELOG.rst +++ b/labrob_description/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package labrob_description ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Added scoring interface (topics and services) +* Contributors: fsuarez6 + 0.1.0 (2014-04-07) ------------------ * Initial release diff --git a/labrob_gazebo/CHANGELOG.rst b/labrob_gazebo/CHANGELOG.rst index 6d64402..0083cfa 100644 --- a/labrob_gazebo/CHANGELOG.rst +++ b/labrob_gazebo/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package labrob_gazebo ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Added scoring interface (topics and services) +* Contributors: fsuarez6 + 0.1.0 (2014-04-07) ------------------ * Initial release diff --git a/labrob_msgs/CHANGELOG.rst b/labrob_msgs/CHANGELOG.rst new file mode 100644 index 0000000..8ab60a9 --- /dev/null +++ b/labrob_msgs/CHANGELOG.rst @@ -0,0 +1,8 @@ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Changelog for package labrob_msgs +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Forthcoming +----------- +* Added scoring interface (topics and services) +* Contributors: fsuarez6 diff --git a/labrob_msgs/CMakeLists.txt b/labrob_msgs/CMakeLists.txt new file mode 100644 index 0000000..dee7421 --- /dev/null +++ b/labrob_msgs/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 2.8.3) +project(labrob_msgs) + +find_package(catkin REQUIRED COMPONENTS + message_generation nav_msgs) + +add_service_files( + FILES + GetMapPercentage.srv +) + +generate_messages(DEPENDENCIES nav_msgs std_msgs) + +catkin_package( +CATKIN_DEPENDS + message_runtime +) + + +include_directories( + ${catkin_INCLUDE_DIRS} +) + diff --git a/labrob_msgs/package.xml b/labrob_msgs/package.xml new file mode 100644 index 0000000..4a3ffd6 --- /dev/null +++ b/labrob_msgs/package.xml @@ -0,0 +1,22 @@ + + + labrob_msgs + 0.1.0 + The labrob_msgs package + + Francisco Suarez-Ruiz + BSD + + http://www.romin.upm.es/wiki/ + https://github.com/fsuarez6/labrob + Francisco Suarez-Ruiz + + catkin + nav_msgs + message_generation + + nav_msgs + message_runtime + + + diff --git a/labrob_msgs/srv/GetMapPercentage.srv b/labrob_msgs/srv/GetMapPercentage.srv new file mode 100644 index 0000000..40247b4 --- /dev/null +++ b/labrob_msgs/srv/GetMapPercentage.srv @@ -0,0 +1,3 @@ +nav_msgs/OccupancyGrid map +--- +float32 percentage_covered diff --git a/labrob_worlds/CHANGELOG.rst b/labrob_worlds/CHANGELOG.rst new file mode 100644 index 0000000..48497d7 --- /dev/null +++ b/labrob_worlds/CHANGELOG.rst @@ -0,0 +1,8 @@ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Changelog for package labrob_worlds +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Forthcoming +----------- +* Added scoring interface (topics and services) +* Contributors: fsuarez6 diff --git a/labrob_worlds/CMakeLists.txt b/labrob_worlds/CMakeLists.txt index f0bbb59..c6c06a9 100644 --- a/labrob_worlds/CMakeLists.txt +++ b/labrob_worlds/CMakeLists.txt @@ -5,6 +5,8 @@ find_package(catkin REQUIRED COMPONENTS gazebo_ros roscpp rospy + labrob_msgs + nav_msgs ) @@ -12,8 +14,12 @@ catkin_package( CATKIN_DEPENDS roscpp gazebo_ros + labrob_msgs + nav_msgs ) +catkin_python_setup() + find_package(gazebo REQUIRED) link_directories(${GAZEBO_LIBRARY_DIRS}) diff --git a/labrob_worlds/launch/crazy_maze.launch b/labrob_worlds/launch/crazy_maze.launch index eae99cd..092e22f 100644 --- a/labrob_worlds/launch/crazy_maze.launch +++ b/labrob_worlds/launch/crazy_maze.launch @@ -12,16 +12,11 @@ - - + + + + + + diff --git a/labrob_worlds/models/crazy_coins/model.sdf b/labrob_worlds/models/crazy_coins/model.sdf index d2654bf..7210f11 100644 --- a/labrob_worlds/models/crazy_coins/model.sdf +++ b/labrob_worlds/models/crazy_coins/model.sdf @@ -266,7 +266,9 @@ + coin_2 labrob + 10.0 1.570796327 diff --git a/labrob_worlds/package.xml b/labrob_worlds/package.xml index f83b0e5..4758f05 100644 --- a/labrob_worlds/package.xml +++ b/labrob_worlds/package.xml @@ -16,12 +16,14 @@ gazebo_ros roscpp rospy - geometry_msgs + labrob_msgs + nav_msgs gazebo_ros roscpp rospy - geometry_msgs + labrob_msgs + nav_msgs diff --git a/labrob_worlds/scripts/challenge_map_server.py b/labrob_worlds/scripts/challenge_map_server.py new file mode 100755 index 0000000..2ebf461 --- /dev/null +++ b/labrob_worlds/scripts/challenge_map_server.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +import rospy, math +from labrob_msgs.srv import GetMapPercentage + +from nav_msgs.msg import OccupancyGrid + +class ChallengeMapServer: + def __init__(self): + rospy.init_node('challenge_map_server') + + # Initial values + size_m2 = rospy.get_param('/map_size_m2', 400.0) + resolution = rospy.get_param('/map_resolution', 0.05) + self.size_map = size_m2/resolution + + # Advertise the service + s = rospy.Service('get_percent_map_completed', GetMapPercentage, self.handle_map) + + rospy.loginfo('Challenge begun. Map size: %d squares' % int(self.size_map)); + + def handle_map(self, req): + rospy.loginfo('Received map. Calculating Percentage Completed...'); + + n_squares_mapped = sum(1 for x in req.map.data if x >= 0) + percentage = float(n_squares_mapped)/float(self.size_map) + + rospy.loginfo('Map Complete: '+str(100.0 * percentage)+'%') + + return percentage + + +if __name__ == "__main__": + ChallengeMapServer() + rospy.spin() diff --git a/labrob_worlds/setup.py b/labrob_worlds/setup.py new file mode 100644 index 0000000..cf3dbd7 --- /dev/null +++ b/labrob_worlds/setup.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +from distutils.core import setup +from catkin_pkg.python_setup import generate_distutils_setup + +# fetch values from package.xml +setup_args = generate_distutils_setup( + packages=['labrob_worlds'], + package_dir={'': 'scripts'}) + +setup(**setup_args) diff --git a/labrob_worlds/src/coins_manager_plugin.cpp b/labrob_worlds/src/coins_manager_plugin.cpp index ac5c49d..c2dbbaf 100644 --- a/labrob_worlds/src/coins_manager_plugin.cpp +++ b/labrob_worlds/src/coins_manager_plugin.cpp @@ -38,6 +38,8 @@ * \desc Plugin for animation of all the coins within the maze */ #include +#include +#include #include @@ -62,12 +64,23 @@ class CoinsManager : public ModelPlugin physics::Link_V links_; physics::Joint_V joints_; + // ROS STUFF + ros::NodeHandle* rosnode_; + ros::Publisher coins_publisher_; + ros::Publisher complete_publisher_; + double spin_velocity_; double coin_radius_; int total_coins_; + bool course_complete_; + std::string plugin_namespace_; std::string robot_name_; + std::string goal_coin_; event::ConnectionPtr update_connection_; - common::Time last_time_; + // Update Rate + double update_rate_; + double update_period_; + common::Time last_update_time_; /* Constructor */ public: CoinsManager() : ModelPlugin() { @@ -76,6 +89,7 @@ class CoinsManager : public ModelPlugin /* Destructor */ public: virtual ~CoinsManager() { + delete rosnode_; event::Events::DisconnectWorldUpdateBegin(update_connection_); } @@ -91,13 +105,32 @@ class CoinsManager : public ModelPlugin // Set the coin radius coin_radius_ = 1.0; - // Set the coins spin velocity + // Read all the plugin parameters + robot_name_ = "labrob"; + if (!_sdf->HasElement("robot_name")) + ROS_WARN_STREAM("coins_manager_plugin missing parameter, using [" << robot_name_ << "]"); + else + robot_name_ = _sdf->GetElement("robot_name")->Get(); + + goal_coin_ = "coin_1"; + if (!_sdf->HasElement("goal_coin")) + ROS_WARN_STREAM("coins_manager_plugin missing parameter, using [" << goal_coin_ << "]"); + else + goal_coin_ = _sdf->GetElement("goal_coin")->Get(); + + update_rate_ = 100.0; + if (!_sdf->HasElement("update_rate")) + ROS_WARN("coins_manager_plugin missing , defaults to %f", update_rate_); + else + update_rate_ = _sdf->GetElement("update_rate")->Get(); + spin_velocity_ = 1.570796327; if (!_sdf->HasElement("spin_velocity")) - gzwarn << "coins_manager_plugin missing parameter, using [" << spin_velocity_ << "] rad."<< endl; + ROS_WARN_STREAM("coins_manager_plugin missing parameter, using [" << spin_velocity_ << "] rad/s"); else spin_velocity_ = _sdf->GetElement("spin_velocity")->Get(); + // Make spin the coins for (int i = 0; i < links_.size(); ++i) { // Randomize the spin direction @@ -105,44 +138,53 @@ class CoinsManager : public ModelPlugin links_[i]->SetAngularVel(math::Vector3(0, 0, spin_velocity_*spin_dir)); } total_coins_ = links_.size(); - gzdbg << "Found [" << total_coins_ << "] coins!" << endl; + ROS_DEBUG_STREAM("Found [" << total_coins_ << "] coins!"); // Make sure the ROS node for Gazebo has already been initialized if (!ros::isInitialized()) { - gzerr << "A ROS node for Gazebo has not been initialized, unable to load plugin. " - << "Load the Gazebo system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)" << endl; + ROS_FATAL_STREAM("A ROS node for Gazebo has not been initialized, unable to load plugin. " + << "Load the Gazebo system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)"); return; } - // Reset Time - last_time_ = world_->GetSimTime(); + + plugin_namespace_ = "/"; + rosnode_ = new ros::NodeHandle(plugin_namespace_); + + // ROS: Setup publishers + coins_publisher_ = rosnode_->advertise("coins_remaining", 1); + complete_publisher_ = rosnode_->advertise("course_complete", 1); + + // Initialize update rate stuff + + if (update_rate_ > 0.0) + update_period_ = 1.0 / update_rate_; + else + update_period_ = 0.0; + last_update_time_ = world_->GetSimTime(); + // Listen to the update event. This event is broadcast every simulation iteration. update_connection_ = event::Events::ConnectWorldUpdateBegin( boost::bind(&CoinsManager::UpdateChild, this)); - - // Wait for the robot to be spawn - robot_name_ = "labrob"; - if (!_sdf->HasElement("robot_name")) - gzwarn << "coins_manager_plugin missing parameter, using [" << robot_name_ << "] rad."<< endl; - else - robot_name_ = _sdf->GetElement("robot_name")->Get(); + + ROS_INFO("Starting CoinsManager Plugin (ns = %s)!", plugin_namespace_.c_str()); + course_complete_ = false; - BlueMsg("coins_manager_plugin successfully loaded!"); } /* Update the plugin */ - // TODO: Need to publish interest information to ROS: Total coins, collected coins, reached the goal? private: void UpdateChild() { math::Pose robot_pose; math::Vector3 position_diff; double distance; common::Time current_time = world_->GetSimTime(); + double seconds_since_last_update = (current_time - last_update_time_).Double(); - if (current_time > last_time_) + if (seconds_since_last_update > update_period_) { // Put the 'intelligence' in here! - if (!robot_model_) + if (!robot_model_) // Wait for the robot to be spawn robot_model_ = world_->GetModel(robot_name_); else { @@ -150,27 +192,31 @@ class CoinsManager : public ModelPlugin robot_pose = robot_model_->GetWorldPose(); for (int i = 0; i < links_.size(); ++i) { - // TODO: Should use GetBoundingBox() and check the intersection + // TODO: Should use links_[i]->GetBoundingBox() and check the intersection math::Pose coin_pose = links_[i]->GetWorldPose(); position_diff = coin_pose.pos - robot_pose.pos; distance = sqrt(pow(position_diff.x, 2) + pow(position_diff.y, 2)); // If the robot is close enough delete the coin if (distance < coin_radius_) { + // Check if We got the goal coin + if (goal_coin_.compare(links_[i]->GetName()) == 0) + course_complete_ = true; model_->RemoveChild(links_[i]); links_.erase(links_.begin() + i); } } - } - last_time_ = current_time; + } + // Publish topics + std_msgs::Int32 coins_msg; + coins_msg.data = links_.size(); + coins_publisher_.publish(coins_msg); + std_msgs::Bool complete_msg; + complete_msg.data = course_complete_; + complete_publisher_.publish(complete_msg); + last_update_time_+= common::Time(update_period_); } } - - /* Custom log messages */ - private: void BlueMsg(std::string msg) { - gzmsg << "\033[94m" << msg << "\033[0m" << endl; } - private: void GreenMsg(std::string msg) { - gzmsg << "\033[92m" << msg << "\033[0m" << endl; } }; GZ_REGISTER_MODEL_PLUGIN(CoinsManager)