## 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