-
Notifications
You must be signed in to change notification settings - Fork 316
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added random_generator package, including an action interface, action…
… client and action server, all in one. Signed-off-by: Tirine <[email protected]>
- Loading branch information
Showing
7 changed files
with
400 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
cmake_minimum_required(VERSION 3.8) | ||
project(random_generator) | ||
|
||
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") | ||
add_compile_options(-Wall -Wextra -Wpedantic) | ||
endif() | ||
|
||
# find dependencies | ||
find_package(ament_cmake REQUIRED) | ||
find_package(rclcpp REQUIRED) | ||
find_package(rclcpp_action REQUIRED) | ||
find_package(rclcpp_components REQUIRED) | ||
find_package(rosidl_default_generators REQUIRED) | ||
|
||
# Action Interface | ||
rosidl_generate_interfaces(${PROJECT_NAME} | ||
"action/Randomizer.action" | ||
) | ||
ament_export_dependencies( | ||
rosidl_default_runtime | ||
) | ||
|
||
# Action Client | ||
add_library(action_client SHARED | ||
src/randomizer_action_client.cpp) | ||
target_include_directories(action_client PRIVATE | ||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> | ||
$<INSTALL_INTERFACE:include>) | ||
target_compile_definitions(action_client | ||
PRIVATE "RANDOM_GENERATOR_BUILDING_DLL") | ||
ament_target_dependencies(action_client | ||
"rclcpp" | ||
"rclcpp_action" | ||
"rclcpp_components") | ||
rclcpp_components_register_node(action_client | ||
PLUGIN "random_generator::RandomizerActionClient" | ||
EXECUTABLE randomizer_action_client) | ||
install(TARGETS action_client | ||
ARCHIVE DESTINATION lib | ||
LIBRARY DESTINATION lib | ||
RUNTIME DESTINATION bin) | ||
|
||
# Action Server | ||
add_library(action_server SHARED | ||
src/randomizer_action_server.cpp) | ||
target_include_directories(action_server PRIVATE | ||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> | ||
$<INSTALL_INTERFACE:include>) | ||
target_compile_definitions(action_server | ||
PRIVATE "RANDOM_GENERATOR_BUILDING_DLL") | ||
ament_target_dependencies(action_server | ||
"rclcpp" | ||
"rclcpp_action" | ||
"rclcpp_components") | ||
rclcpp_components_register_node(action_server | ||
PLUGIN "random_generator::RandomizerActionServer" | ||
EXECUTABLE randomizer_action_server) | ||
install(TARGETS action_server | ||
ARCHIVE DESTINATION lib | ||
LIBRARY DESTINATION lib | ||
RUNTIME DESTINATION bin) | ||
|
||
# Include the action interface to the client and server, both the library and executable | ||
rosidl_target_interfaces(action_server | ||
${PROJECT_NAME} "rosidl_typesupport_cpp") | ||
rosidl_target_interfaces(action_client | ||
${PROJECT_NAME} "rosidl_typesupport_cpp") | ||
rosidl_target_interfaces(randomizer_action_client | ||
${PROJECT_NAME} "rosidl_typesupport_cpp") | ||
rosidl_target_interfaces(randomizer_action_server | ||
${PROJECT_NAME} "rosidl_typesupport_cpp") | ||
|
||
# Finally | ||
if(BUILD_TESTING) | ||
find_package(ament_lint_auto REQUIRED) | ||
# the following line skips the linter which checks for copyrights | ||
# uncomment the line when a copyright and license is not present in all source files | ||
#set(ament_cmake_copyright_FOUND TRUE) | ||
# the following line skips cpplint (only works in a git repo) | ||
# uncomment the line when this package is not in a git repo | ||
#set(ament_cmake_cpplint_FOUND TRUE) | ||
ament_lint_auto_find_test_dependencies() | ||
endif() | ||
|
||
ament_package() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# A single package with the action interface and the client and server. | ||
|
||
This package contains an few example which show how to create a single package with the interface, client and server, all in one. | ||
|
||
The main difference between the msg/srv interface that was included into a package with it's client and service is that an action client and server needs to have both the library and executable included in the rosidl_typesupport_cpp in the CMakeLists file. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
uint16 number_of_values | ||
float64 min_val | ||
float64 max_val | ||
--- | ||
float64[] random_values | ||
--- | ||
uint16 number_of_random_values_calculated | ||
float64 new_random_value |
44 changes: 44 additions & 0 deletions
44
rclcpp/actions/random_generator/include/random_generator/visibility_control.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#ifndef RANDOM_GENERATOR__VISIBILITY_CONTROL_H_ | ||
#define RANDOM_GENERATOR__VISIBILITY_CONTROL_H_ | ||
|
||
#ifdef __cplusplus | ||
extern "C" | ||
{ | ||
#endif | ||
|
||
// This logic was borrowed (then namespaced) from the examples on the gcc wiki: | ||
// https://gcc.gnu.org/wiki/Visibility | ||
|
||
#if defined _WIN32 || defined __CYGWIN__ | ||
#ifdef __GNUC__ | ||
#define RANDOM_GENERATOR_EXPORT __attribute__ ((dllexport)) | ||
#define RANDOM_GENERATOR_IMPORT __attribute__ ((dllimport)) | ||
#else | ||
#define RANDOM_GENERATOR_EXPORT __declspec(dllexport) | ||
#define RANDOM_GENERATOR_IMPORT __declspec(dllimport) | ||
#endif | ||
#ifdef RANDOM_GENERATOR_BUILDING_DLL | ||
#define RANDOM_GENERATOR_PUBLIC RANDOM_GENERATOR_EXPORT | ||
#else | ||
#define RANDOM_GENERATOR_PUBLIC RANDOM_GENERATOR_IMPORT | ||
#endif | ||
#define RANDOM_GENERATOR_PUBLIC_TYPE RANDOM_GENERATOR_PUBLIC | ||
#define RANDOM_GENERATOR_LOCAL | ||
#else | ||
#define RANDOM_GENERATOR_EXPORT __attribute__ ((visibility("default"))) | ||
#define RANDOM_GENERATOR_IMPORT | ||
#if __GNUC__ >= 4 | ||
#define RANDOM_GENERATOR_PUBLIC __attribute__ ((visibility("default"))) | ||
#define RANDOM_GENERATOR_LOCAL __attribute__ ((visibility("hidden"))) | ||
#else | ||
#define RANDOM_GENERATOR_PUBLIC | ||
#define RANDOM_GENERATOR_LOCAL | ||
#endif | ||
#define RANDOM_GENERATOR_PUBLIC_TYPE | ||
#endif | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif // RANDOM_GENERATOR__VISIBILITY_CONTROL_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?xml version="1.0"?> | ||
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> | ||
<package format="3"> | ||
<name>random_generator</name> | ||
<version>0.0.0</version> | ||
<description>TODO: Package description</description> | ||
<maintainer email="[email protected]">tirine</maintainer> | ||
<license>TODO: License declaration</license> | ||
|
||
<buildtool_depend>ament_cmake</buildtool_depend> | ||
<buildtool_depend>rosidl_default_generators</buildtool_depend> | ||
|
||
<depend>randomizer_action_interface</depend> | ||
<depend>action_msgs</depend> | ||
<depend>rclcpp</depend> | ||
<depend>rclcpp_action</depend> | ||
<depend>rclcpp_components</depend> | ||
|
||
<member_of_group>rosidl_interface_packages</member_of_group> | ||
|
||
<test_depend>ament_lint_auto</test_depend> | ||
<test_depend>ament_lint_common</test_depend> | ||
|
||
<export> | ||
<build_type>ament_cmake</build_type> | ||
</export> | ||
</package> |
116 changes: 116 additions & 0 deletions
116
rclcpp/actions/random_generator/src/randomizer_action_client.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// Copyright 2016 Open Source Robotics Foundation, Inc. | ||
|
||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
|
||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include <functional> | ||
#include <future> | ||
#include <memory> | ||
#include <sstream> | ||
#include <string> | ||
|
||
#include "random_generator/action/randomizer.hpp" | ||
|
||
#include "rclcpp/rclcpp.hpp" | ||
#include "rclcpp_action/rclcpp_action.hpp" | ||
#include "rclcpp_components/register_node_macro.hpp" | ||
|
||
namespace random_generator { | ||
class RandomizerActionClient : public rclcpp::Node { | ||
public: | ||
using Randomizer = action::Randomizer; | ||
using GoalHandleRandomizer = rclcpp_action::ClientGoalHandle<Randomizer>; | ||
|
||
explicit RandomizerActionClient(const rclcpp::NodeOptions& options) | ||
: Node("randomizer_action_client", options) { | ||
this->client_ptr_ = rclcpp_action::create_client<Randomizer>(this, "randomizer"); | ||
|
||
this->timer_ = this->create_wall_timer(std::chrono::milliseconds(500), | ||
std::bind(&RandomizerActionClient::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 = Randomizer::Goal(); | ||
goal_msg.number_of_values = 10; | ||
goal_msg.min_val = 0.5; | ||
goal_msg.max_val = 9.5; | ||
|
||
RCLCPP_INFO(this->get_logger(), "Sending goal"); | ||
|
||
auto send_goal_options = rclcpp_action::Client<Randomizer>::SendGoalOptions(); | ||
send_goal_options.goal_response_callback = | ||
std::bind(&RandomizerActionClient::goal_response_callback, this, _1); | ||
send_goal_options.feedback_callback = | ||
std::bind(&RandomizerActionClient::feedback_callback, this, _1, _2); | ||
send_goal_options.result_callback = | ||
std::bind(&RandomizerActionClient::result_callback, this, _1); | ||
this->client_ptr_->async_send_goal(goal_msg, send_goal_options); | ||
} | ||
|
||
private: | ||
rclcpp_action::Client<Randomizer>::SharedPtr client_ptr_; | ||
rclcpp::TimerBase::SharedPtr timer_; | ||
|
||
void goal_response_callback(std::shared_future<GoalHandleRandomizer::SharedPtr> future) { | ||
auto goal_handle = future.get(); | ||
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(GoalHandleRandomizer::SharedPtr, | ||
const std::shared_ptr<const Randomizer::Feedback> feedback) { | ||
std::stringstream ss; | ||
ss << std::setprecision(6); | ||
ss << "Next random number: " << feedback->new_random_value | ||
<< ". \t Done: " << feedback->number_of_random_values_calculated << " values."; | ||
RCLCPP_INFO(this->get_logger(), ss.str().c_str()); | ||
} | ||
|
||
void result_callback(const GoalHandleRandomizer::WrappedResult& result_handle) { | ||
switch (result_handle.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; | ||
} | ||
std::stringstream ss; | ||
ss << "Result received: "; | ||
for (auto number : result_handle.result->random_values) { | ||
ss << number << " "; | ||
} | ||
RCLCPP_INFO(this->get_logger(), ss.str().c_str()); | ||
rclcpp::shutdown(); | ||
} | ||
}; // class RandomizerActionClient | ||
|
||
} // namespace random_generator | ||
|
||
RCLCPP_COMPONENTS_REGISTER_NODE(random_generator::RandomizerActionClient) |
Oops, something went wrong.