Ada-Europe 2019 Warsaw 1/43 RCLAda, or bringing Ada to the Robotic Operating System A. R. Mosteo 2019-jun-13
Ada-Europe 2019 • Motivation & Context Warsaw 2/43 – About us – What is ROS2 What is – Why Ada ROS2? And why Ada? – ROS2 example • RCLAda Architecture – Methodology CONTENTS – Integration • RCLAda API – Examples
Ada-Europe 2019 Warsaw 3/43 Research group Robotics, Perception and Real-Time group - RoPeRT University of Zaragoza Engineering Research Institute of Aragon
Ada-Europe Optimal Real-time Underground 2019 Warsaw distributed multi-hop drone 4/43 coordination communication reconnaissance http://robots.unizar.es/ RoPeRT
Ada-Europe 2019 It is now possible to write ROS2 Warsaw 5/43 nodes in Ada 2012 In a nutshell (with minimal CMake knowledge) Ada coin author: Steven Craeynest
About ROS 6
Ada-Europe 2019 7/43 • Robot Operating System Warsaw – But not really “The Robot Operating System (ROS) is a set of software libraries and tools that help you build robot applications. From drivers to state-of-the-art algorithms , and with powerful developer tools, ROS has what you need for your next robotics project. And it's all open source .” What is ROS Main OSRF project (10 years now)
Ada-Europe 2019 Warsaw 8/43 • Collection of Debian/Ubuntu packages ready to use – Sensor/platform/actuator drivers – High-level algorithms Colcon Build system ( ∈ “tools”) • ROS2 Main Parts – Heterogeneous language environment – Nodes isolated as processes/threads • Intercommunication facilities (“plumbing”) – Message publishing – Remote Procedure Calls – Actions
Ada-Europe 2019 9/43 PR2: the kick-off robot Warsaw PR2 https://www.youtube.com/watch?v=c3Cq0sy4TBs
Ada-Europe 2019 Warsaw • ROS support widespread 10/43 – Expected in research/academia contexts – Either by 1st or 3rd parties Academia & Research
Ada-Europe 2019 Warsaw 11/43 Why ROS
Ada-Europe 2019 Warsaw ROS2 vs ROS 12/43 • More emphasis on – Embedded (microcontrollers) • ROS has been mostly a linux affair – Real-time • Coming from firm/soft real-time – Actual readiness for industrial settings • Long lived processes vs short experiments • Standard DDS for data transport Why ROS2 – Swappable implementation • Traditional strongholds of Ada
Ada-Europe 2019 At the time of this writing (may’19) Warsaw 13/43 • Working Groups on – Real-time – Safety-critical • Already seen interest in SPARK ROS2 hot topics
Ada-Europe 2019 Warsaw • ROS2 “program” 14/43 – Set of nodes (processes) • Found in ROS packages – Interconnected (DDS) by • Topics Down to business – Publish, Subscribe • Services – Request + Response client libraries – Supported languages rclcpp rclpy • C++, Python (Client APIs) ROS2 client API (rcl) • C (low-level API)
Ada-Europe 2019 Warsaw 15/43 Nodes + Topics
Ada-Europe 2019 Warsaw Ada ROS2 packages 16/43 1. $ ros2 pkg create rclada write code rosidl_generator_ada Workflow (developer) 2. $ colcon build compile code CMake functions 3. $ ros2 launch rclada_common execute code
Ada-Europe 2019 // CMakeLists.txt Warsaw Standard CMake project declaration 17/43 cmake_minimum_required(VERSION 3.5) Import Ada-specific CMake functions project(my_ada_ros2_project VERSION 0.1.0) Import Ada environment find_package(rclada_common REQUIRED) ada_begin_package() Import RCLAda GPR projects - RCLAda: Nodes, Topics, etc find_package(rclada REQUIRED) - ROSIDL_Ada: Messages CMake example find_package(rosidl_generator_ada REQUIRED) Declare our Ada GNAT project ada_add_executables( my_ada_project # CMake target name ${PROJECT_SOURCE_DIR} # Path to *.gpr bin # Path to binaries my_ada_main) # Binaries (nodes) Export our additions to downstream ada_end_package()
Ada-Europe 2019 • ada_begin_package() rclada_common Warsaw 18/43 • ada_end_package() Needed to propagate Ada information through ROS2 packages Support for colcon_cmake • ada_add_executables(TARGET SRCDIR DSTDIR EXECUTABLES) Declares an Ada executable to be built and exported (tab completion) • ada_add_library(TARGET SRCDIR GPRFILE) Declares an Ada library project to be built and exported to other Ada packages • ada_import_msgs(PKG_NAME) Generates bindings to the typesupport handle functions Could disappear once RCLAda is integrated in build farm • ada_generate_binding(TARGET SRCDIR GPRFILE INCLUDE) Invokes the binding generator in the context of an Ada project
class Talker : public rclcpp::Node Ada-Europe 2019 { procedure Talker is Warsaw public: Support : constant ROSIDL.Typesupport.Message_Support := explicit Talker : Node("talker") 19/43 ROSIDL.Typesupport.Get ("std_msgs", "String"); { msg_ = std::make_shared<std_msgs::msg::String>(); Node : Nodes.Node := Nodes.Init (Utils.Command_Name); auto publish_message = [this]() -> void Pub : Publishers.Publisher := Node.Publish { (Support, "/chatter"); msg_->data = Msg : ROSIDL.Dynamic.Message := ROSIDL.Dynamic.Init "Hello World: " + std::to_string(count_++); (Support); pub_->publish(msg_); }; C++ vs Ada example Counter : Positive := 1; pub_ = this->create_publisher procedure Callback (Node : in out Nodes.Node'Class; <std_msgs::msg::String>(topic_name); Timer : in out Timers.Timer; timer_ = this->create_wall_timer(1s, publish_message); Elapsed : Duration) } is private: Txt : constant String := "Hello World:" & Counter'Img; size_t count_ = 1; begin std::shared_ptr<std_msgs::msg::String> msg_; Msg ("data").Set_String (Txt); rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub_; Pub.Publish (Msg); Counter := Counter + 1; rclcpp::TimerBase::SharedPtr timer_; end Callback; }; begin int main(int argc, char * argv[]) Node.Timer_Add (1.0, Callback'Access); { Node.Spin; auto topic = std::string("chatter"); end Talker; auto node = std::make_shared<Talker>(topic); rclcpp::spin(node); }
class Talker : public rclcpp::Node Ada-Europe 2019 { procedure Talker is Warsaw public: Support : constant ROSIDL.Typesupport.Message_Support := explicit Talker : Node("talker") 20/43 ROSIDL.Typesupport.Get ("std_msgs", "String"); { msg_ = std::make_shared<std_msgs::msg::String>(); Node : Nodes.Node := Nodes.Init (Utils.Command_Name); auto publish_message = [this]() -> void Pub : Publishers.Publisher := Node.Publish { (Support, "/chatter"); msg_->data = Msg : ROSIDL.Dynamic.Message := ROSIDL.Dynamic.Init "Hello World: " + std::to_string(count_++); (Support); pub_->publish(msg_); }; C++ vs Ada example Counter : Positive := 1; pub_ = this->create_publisher procedure Callback (Node : in out Nodes.Node'Class; <std_msgs::msg::String>(topic_name); Timer : in out Timers.Timer; timer_ = this->create_wall_timer(1s, publish_message); Elapsed : Duration) } is private: Txt : constant String := "Hello World:" & Counter'Img; size_t count_ = 1; begin std::shared_ptr<std_msgs::msg::String> msg_; Msg ("data").Set_String (Txt); rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub_; Pub.Publish (Msg); Counter := Counter + 1; rclcpp::TimerBase::SharedPtr timer_; end Callback; }; begin int main(int argc, char * argv[]) Node.Timer_Add (1.0, Callback'Access); { Node.Spin; auto topic = std::string("chatter"); end Talker; auto node = std::make_shared<Talker>(topic); rclcpp::spin(node); }
class Talker : public rclcpp::Node Ada-Europe 2019 { procedure Talker is Warsaw public: Support : constant ROSIDL.Typesupport.Message_Support := explicit Talker : Node("talker") 21/43 ROSIDL.Typesupport.Get ("std_msgs", "String"); { msg_ = std::make_shared<std_msgs::msg::String>(); Node : Nodes.Node := Nodes.Init (Utils.Command_Name); auto publish_message = [this]() -> void Pub : Publishers.Publisher := Node.Publish { (Support, "/chatter"); msg_->data = Msg : ROSIDL.Dynamic.Message := ROSIDL.Dynamic.Init "Hello World: " + std::to_string(count_++); (Support); pub_->publish(msg_); }; C++ vs Ada example Counter : Positive := 1; pub_ = this->create_publisher procedure Callback (Node : in out Nodes.Node'Class; <std_msgs::msg::String>(topic_name); Timer : in out Timers.Timer; timer_ = this->create_wall_timer(1s, publish_message); Elapsed : Duration) } is private: Txt : constant String := "Hello World:" & Counter'Img; size_t count_ = 1; begin std::shared_ptr<std_msgs::msg::String> msg_; Msg ("data").Set_String (Txt); rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub_; Pub.Publish (Msg); Counter := Counter + 1; rclcpp::TimerBase::SharedPtr timer_; end Callback; }; begin int main(int argc, char * argv[]) Node.Timer_Add (1.0, Callback'Access); { Node.Spin; auto topic = std::string("chatter"); end Talker; auto node = std::make_shared<Talker>(topic); rclcpp::spin(node); }
Recommend
More recommend