## For instruction on writing tutorials ## http://www.ros.org/wiki/WritingTutorials #################################### ##FILL ME IN #################################### ## for a custom note with links: ## note = ## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links ## note.0=[[rosserial_tivac/Tutorials/TivaWare Setup|Tivaware and toolchain setup]] ## descriptive title for the tutorial ## title = RGB service ## multi-line description to be displayed in search ## description = EK-TM4C123GXL board over CDC USB device provides a custom message service for changing LED color. ## the next tutorial description (optional) ## next = ## links to next tutorial (optional) ## next.0.link= ## next.1.link= ## what level user is this tutorial for ## level= IntermediateCategory ## keywords = #################################### <<IncludeCSTemplate(TutorialCSHeaderTemplate)>> <<TableOfContents(4)>> ##startpage == Introduction == The last tutorial of this series will show you how to create a custom service message and service server over rosserial. The code relative to this tutorial can be found in the directory `rgb_srv`. == ColoRGBA service message == Let's analyze the message file found in `srv/ColorRGBA.srv`. {{{ std_msgs/ColorRGBA color --- bool result }}} As a request we have a color field, of type `std_msgs/ColorRGBA` and as response we get a `bool` result. === package.xml & CMakeLists.txt === On the package's package.xml and top level CMakeLists.txt we need dependencies and rules to generate the new service message. ==== package.xml ==== Dependencies on `package.xml`: {{{ <build_depend>message_generation</build_depend> <run_depend>message_runtime</run_depend> }}} ==== CMakeLists.xml ==== {{{ (...) find_package(catkin REQUIRED COMPONENTS message_generation rosserial_client rosserial_tivac std_msgs ) add_service_files( FILES ColorRGBA.srv ) generate_messages( DEPENDENCIES std_msgs ) catkin_package( CATKIN_DEPENDS message_runtime std_msgs ) (...) }}} The required dependencies and instructions to generate the service message files. == Code == Similarly to the subscriber tutorial, we need to register a service server and assign to it a callback to handle the incoming requests and produce responses. {{{ #!cplusplus block=srccode #include <stdbool.h> #include <stdint.h> // TivaC specific includes extern "C" { #include <driverlib/sysctl.h> #include <driverlib/gpio.h> #include <rgb.h> } // ROS includes #include <ros.h> // Our custom service message #include "rosserial_tivac_tutorials/ColorRGBA.h" uint32_t current_color[3] = {0xFFFE, 0xFFFE, 0xFFFE}; float current_intensity = 1.f; void color_cb(const rosserial_tivac_tutorials::ColorRGBARequest& req, rosserial_tivac_tutorials::ColorRGBAResponse& resp) { current_color[0] = req.color.r * 0xFFFE; current_color[1] = req.color.g * 0xFFFE; current_color[2] = req.color.b * 0xFFFE; current_intensity = req.color.a; RGBSet(current_color, current_intensity); resp.result = true; } // ROS nodehandle and subscriber ros::NodeHandle nh; ros::ServiceServer<rosserial_tivac_tutorials::ColorRGBARequest, rosserial_tivac_tutorials::ColorRGBAResponse> rgb_service("led", &color_cb); int main(void) { // TivaC application specific code MAP_FPUEnable(); MAP_FPULazyStackingEnable(); // TivaC system clock configuration. Set to 80MHz. MAP_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN); // Setup RGB driver RGBInit(0); RGBSet(current_color, current_intensity); // ROS nodehandle initialization and topic registration nh.initNode(); nh.advertiseService<rosserial_tivac_tutorials::ColorRGBARequest, rosserial_tivac_tutorials::ColorRGBAResponse>(rgb_service); bool nh_prev_state = false; while (1) { // If subscribed, enable RGB driver if (nh.connected() && !nh_prev_state) { RGBEnable(); nh_prev_state = true; } if (!nh.connected() && nh_prev_state) { RGBDisable(); nh_prev_state = false; } // Handle all communications and callbacks. nh.spinOnce(); // Delay for a bit. nh.getHardware()->delay(1000); } } }}} The relevant parts for this tutorial are herein explained. <<CodeRef(srccode,29,31)>> Node handle instantiation and service server definition. The service is available over the service topic `/led`, of type `rosserial_tivac_tutorials::ColorRGBA`, handled by the `color_cb` callback. <<CodeRef(srccode,47,49)>> After initializing the node, register the service server to the callback queue. <<CodeRef(srccode,17,27)>> The service callback receives the request, converting the values from the message to the LED driver. It then always returns a `true` result. == Build, flash and test == {{{ catkin_make catkin_make rosserial_tivac_tutorials_rgb_led_flash }}} Don't forget to connect the device USB port to your computer! Run `roscore` and `run serial_node.py` from `rosserial_python` on the correct port `/dev/ttyACM#`. {{{ roscore }}} When you successfully connect using `serial_node the LED will light up. {{{ rosrun rosserial_python serial_node.py _port:=/dev/ttyACM0 }}} On a new terminal window, call the service with a new color. {{{ rosservice call /led std_msgs/ColorRGBA "r: 0.0 g: 0.0 b: 1.0 a: 1.0" }}} It should change to the brightest blue. ##endpage ## AUTOGENERATED DO NOT DELETE ## TutorialCategory ## FILL IN THE STACK TUTORIAL CATEGORY HERE