<?xml version="1.0" encoding="utf-8"?><!DOCTYPE article  PUBLIC '-//OASIS//DTD DocBook XML V4.4//EN'  'http://www.docbook.org/xml/4.4/docbookx.dtd'><article><articleinfo><title>Robotica/PlayerStageRoMAA/PlayerDriverRoMAA1/Messages</title><revhistory><revision><revnumber>3</revnumber><date>2011-04-20 22:04:03</date><authorinitials>GonzaloPerezPaina</authorinitials><revremark>organización de la wiki</revremark></revision><revision><revnumber>2</revnumber><date>2010-06-05 22:53:10</date><authorinitials>GonzaloPerezPaina</authorinitials></revision></revhistory></articleinfo><section><title>Procesamiento de mensajes y publicación de datos</title><section><title>ProcessMessage</title><para>ProcessMessage provee de la principal funcionalidad del servidor Player. Diferentes interfaces interactuan unas con otras enviando y recibiendo mensajes a traves de Player. Los diferentes tipos de mensajes pueden verse <ulink url="http://playerstage.sourceforge.net/doc/Player-2.1.0/player/group__message__types.html">aquí</ulink>. Cada interfaz soporta un subconjunto de mensajes. Por ejemplo los tipos de mensajes definidos para la interfaz <emphasis>position2d</emphasis> puden verse <ulink url="http://playerstage.sourceforge.net/doc/Player-2.1.0/player/group__interface__position2d.html">aquí</ulink>. </para><para>Tipos de mensajes </para><itemizedlist><listitem><para><emphasis role="strong">Commands:</emphasis> Se utilizan para darle instrucciones al driver cuando no se requiere una respuesta. La interfaz <emphasis>position2d</emphasis> usa comandos para recibir velocidades para los motores. </para></listitem><listitem><para><emphasis role="strong">Requests:</emphasis> Son mensajes desde otros drivers para acceder a datos que no son publicados regularmente o enviar comandos que requieren algún tipo de respuesta. </para></listitem><listitem><para><emphasis role="strong">Data:</emphasis> Los mensajes de datos son publicados en cada iteracción del loop Main del driver. </para></listitem></itemizedlist></section><section><title>Interface position2d (motor control / odometry)</title><section><title>Publicación de odometría</title><screen><![CDATA[// Update position2d data                                                                              
player_position2d_data_t pos2d_data;                                                                   
memset( &pos2d_data, 0, sizeof( player_position2d_data_t) );                                           
                                                                                                           
romaa_comms->update_odometry();                                                                        
romaa_comms->get_odometry( pos2d_data.pos.px,                                                          
                           pos2d_data.pos.py,                                                          
                           pos2d_data.pos.pa );                                                        
                                                                                                           
this->Publish( this->position2d_addr,                                                                  
                PLAYER_MSGTYPE_DATA, PLAYER_POSITION2D_DATA_STATE,                                     
                (void*)&pos2d_data, sizeof( player_position2d_data_t ), NULL );   ]]></screen><para>utilizando el tipo de dato <ulink url="http://playerstage.sourceforge.net/doc/Player-2.1.0/player/structplayer__position2d__data.html">player_position2d_data_t</ulink>. </para></section><section><title>Actualización de velocidad</title><screen><![CDATA[// CMD Message type (hdr->type)
if ( Message::MatchMessage( hdr, PLAYER_MSGTYPE_CMD,
                            PLAYER_POSITION2D_CMD_VEL,
                            this->position2d_addr ) )
{
  memcpy( &position2d_cmd_vel, data, sizeof( player_position2d_cmd_vel_t) );
]]><![CDATA[
  PLAYER_MSG2(1, "sending motor commands: %f %f",
        position2d_cmd_vel.vel.px,
        position2d_cmd_vel.vel.pa);
]]><![CDATA[
  romaa_comms->set_speed( position2d_cmd_vel.vel.px, position2d_cmd_vel.vel.pa );
  return (0);
  }]]></screen><para>utilizando el tipo de dato <ulink url="http://playerstage.sourceforge.net/doc/Player-2.1.0/player/structplayer__position2d__cmd__vel.html">player_position2d_cmd_vel_t</ulink>. </para></section><section><title>Programa cliente</title><para>Con la publicación de la odometría y la actualización de velocidad hacia el robot, se puede controlar la interfaz <emphasis>position2d</emphasis> a través del siguiente programa cliente (mediante el Proxy <ulink url="http://playerstage.sourceforge.net/doc/Player-2.1.0/player/classPlayerCc_1_1Position2dProxy.html">Position2dProxy</ulink>) </para><screen><![CDATA[#include <iostream>
#include <libplayerc++/playerc++.h>
]]><![CDATA[
int
main( int argc, char *argv[] )
{
  // Connect to the local player process on port 6665
  PlayerCc::PlayerClient romaa_robot( "localhost", 6665 );
]]><![CDATA[
  // Create a position2d proxy
  PlayerCc::Position2dProxy romaa_pos2d( &romaa_robot, 0 );
]]><![CDATA[
  romaa_pos2d.SetSpeed( 10, 0 );
]]><![CDATA[
  std::cout << "loop..." << std::endl;
  for( int i = 0; i < 100; i++ )
  {
    // For 10 seconds move into a circle
    romaa_robot.Read();
]]><![CDATA[
 ";
    std::cout << "px: " << romaa_pos2d.GetXPos() << " - ";
    std::cout << "py: " << romaa_pos2d.GetYPos() << " - ";
    std::cout << "pa: " << romaa_pos2d.GetYaw() << std::endl;
]]><![CDATA[
    usleep(50000);
  }
  return 0;
}]]></screen></section><section><title>Cliente playerv</title><para>El programa cliente <emphasis>playerv</emphasis> se <emphasis role="strong">bloquea</emphasis> al subscribirce a la interfac <emphasis>position2d</emphasis> y no funciona. Esto se debe a que <emphasis>playerv</emphasis> al ejecutarse envia el mensaje PLAYER_POSITION2D_REQ_GET_GEOM solicitando la geometría del robot para así poder dibujar el cuerpo en pantalla. Se responde a este mensaje de la siguiente manera </para><screen><![CDATA[// REQ Message type (hdr->type)
else if ( Message::MatchMessage ( hdr, PLAYER_MSGTYPE_REQ,
                                  PLAYER_POSITION2D_REQ_GET_GEOM,
                                  this->position2d_addr ) ) 
{
  memset( &position2d_geom, 0, sizeof( player_position2d_geom_t ) );
]]><![CDATA[
  romaa_comms->get_geometry_body_size( position2d_geom.size.sw,
      position2d_geom.size.sl,
      position2d_geom.size.sh );
  romaa_comms->get_geometry_odometry_center( position2d_geom.pose.px,
      position2d_geom.pose.py );
]]><![CDATA[
  this->Publish( this->position2d_addr, resp_queue,
                 PLAYER_MSGTYPE_RESP_ACK,
                 PLAYER_POSITION2D_REQ_GET_GEOM,
                 (void*)&position2d_geom, sizeof( player_position2d_geom_t ) );
]]><![CDATA[
  return (0);
}]]></screen><para>utilizando el tipo de dato <ulink url="http://playerstage.sourceforge.net/doc/Player-2.1.0/player/structplayer__position2d__geom.html">player_position2d_geom_t</ulink>. </para></section><section><title>Cliente playerjoy</title><para>El cliente <emphasis>playerjoy</emphasis> al iniciar envia el mensaje PLAYER_POSITION2D_REQ_MOTOR_POWER, que se responde de la siguiente manera </para><screen><![CDATA[else if ( Message::MatchMessage ( hdr, PLAYER_MSGTYPE_REQ,
                                  PLAYER_POSITION2D_REQ_MOTOR_POWER,
                                  this->position2d_addr ) )
{
  this->Publish( this->position2d_addr, resp_queue,
      PLAYER_MSGTYPE_RESP_ACK, PLAYER_POSITION2D_REQ_MOTOR_POWER );
  return (0);
}]]></screen></section></section><section><title>Reset Odometry</title><para>Para el caso de resetear la odometria utilizando el método de <code>Position2dProxy::ResetOdometry()</code> del lado del cliente, en el driver del lado del servidor se detecto el <emphasis role="strong">error</emphasis> que el tipo de mensaje recibido no es PLAYER_POSITION2D_REQ_RESET_ODOM sino PLAYER_POSITION2D_REQ_SET_ODOM; este error (en el subtipo de mensaje) puede estar del lado del server o del cliente, lo cual no fue determinado. </para><screen><![CDATA[  else if ( Message::MatchMessage( hdr, PLAYER_MSGTYPE_REQ,
        PLAYER_POSITION2D_REQ_RESET_ODOM,
        this->position2d_addr ) )
  {
    // reset position to 0,0,0: no args 
    if ( hdr->size != 0 )
    {
      PLAYER_WARN( "Arg to reset position request is wrong size; ignoring" );
      return(-1);
    }
    romaa_comms->reset_odometry();
]]><![CDATA[
    this->Publish( this->position2d_addr, resp_queue,
        PLAYER_MSGTYPE_RESP_ACK,
        PLAYER_POSITION2D_REQ_RESET_ODOM );
    return (0);
  }]]></screen></section><section><title>Set Odometry</title><para>Al llamar el método <code>Position2dProxy::SetOdometry()</code> de lado del cliente, en el servido se obtiene el mensaje correspondiente PLAYER_POSITION2D_REQ_SET_ODOM pero debido al <emphasis role="strong">error</emphasis> antes mencionado en <code>ResetOdometry()</code> se procesa el caso de seteo de odometria en (0,0,0) para salvar dicho error. </para><screen><![CDATA[  else if ( Message::MatchMessage( hdr, PLAYER_MSGTYPE_REQ,
        PLAYER_POSITION2D_REQ_SET_ODOM,
        this->position2d_addr ) )
  {
    if ( hdr->size != sizeof( player_position2d_set_odom_req_t ) )
    {
      PLAYER_WARN("Arg to odometry set requests wrong size; ignoring");
      return(-1);
    }
    player_position2d_set_odom_req_t* set_odom_req =
      (player_position2d_set_odom_req_t*)data;
]]><![CDATA[
    if ( ( set_odom_req->pose.px == 0) &&
        ( set_odom_req->pose.py == 0) &&
        ( set_odom_req->pose.pa == 0) )
    {
      romaa_comms->reset_odometry();
    }
    else
    {
      romaa_comms->set_odometry( set_odom_req->pose.px,
          set_odom_req->pose.py,
          set_odom_req->pose.pa );
    }
]]><![CDATA[
    this->Publish( this->position2d_addr, resp_queue,
        PLAYER_MSGTYPE_RESP_ACK,
        PLAYER_POSITION2D_REQ_SET_ODOM );
    return (0);
  }]]></screen></section></section></article>