Intercambio de información entre Servicios - 2008/03/24 14:14Sigo con mi controlador difuso. Ahora lo que tengo es que el servicio de simulador recojo toda la informacion de los bumpers y del sonar. Lo tengo que comunicar al servicio donde viene implementado el controlador difuso. Para eso conozco lo de Partner que son socios y los iteradores que me recorren el puerto(FIFO) para crear la secuencia de intrucciones.
1º)Pregunta: No hay alguna documentación sobre Partner es que quiero contrastar algunas ideas que tengo en la cabeza.
2º)Pregunta: Para coger el array de double tengo que utilizar el sonar generico o el de cranium.
La idea es que tu servicio de control se suscriba a los servicios que proporcionan información, es decir, a los servicios que representan sensores.
No hay alguna documentación sobre Partner es que quiero contrastar algunas ideas que tengo en la cabeza.
Para hacerte una idea concreta de cómo funciona este modelo de suscripción-notificación puedes echar un vistazo a los tutoriales de servicios que vienen con Robotics Studio. Recuerdo que en los primero tutoriales se define un servicio con un estado muy simple (un contador que se incrementa llamado Tick) y se define una operación llamada IncrementTick.
En cualquier caso, mira los tutoriales de servicios 4 y 5 que son los que se centran en las suscripciones:
Service Tutorial 4 – Supporting Subscriptions This tutorial shows you how enable your service to provide notifications to other services.
Service Tutorial 5 – Subscribing This is the counterpart to the previous tutorial and shows you how to subscribe to other services and explains how to use partner services.
En definitiva, como los servicios que usas que representan los sensores soportan suscripciones, sólo necesitas suscribirte a ellos desde tu servicio de control, así recibirás sus notificaciones de cambio de estado sin tener que realizar ningún tipo de polling. Si no ves claro cómo se hace esto, dímelo y te pongo un ejemplo con fragmentos de mi código..
Para coger el array de double tengo que utilizar el sonar generico o el de cranium.
Puedes usar perfectamente el sonar genérico, ya que la definición del estado es la misma.Raúl Arrabales Moreno. conscious-robots.com/raul
The administrator has disabled public write access. Please, register to participate in the
forum.
El problema esta cuando activo el Arbiter.Receive<?1>, tengo que esperar a que se actualize el SonarState pero me da error.¿A lo Mejor es que el tipo de dato que se tiene que recibir no es SonarState? ¿Tal vez no sea SonarState de tipo Message como pone en la ayuda?
Mandame el ejemplo para la subcribcion del sonar.
PD: Además indicame como poner el codigo de C# como lo pones tu.
UN SALUDO
The administrator has disabled public write access. Please, register to participate in the
forum.
Raúl
Moderator Moderator
Posts: 444
Karma: 6
Re:Intercambio de información entre Servicios - 2008/03/26 15:38A priori no veo que el código que has escrito esté mal. Ah bueno, el puerto que usas para escuchar las notificaciones tiene que se un puerto de tu servicio (por ejemplo el _mainPort) y no el puerto de notificaciones del sonar, ese sólo lo usas para la suscripción. ¿Qué error te da exactamente?
Copio a continuación el código que uso en uno de mis servicios para conectarme a un sonar genérico y recibir notificaciones cuando cambia su estado (es decir, cuando cambian los valores de medida del array de doubles que tiene el estado de sonar genérico):
Code:
// Raul - Sonar generic contract
using pxsonar = Microsoft.Robotics.Services.Sonar.Proxy;
...
// Sonar Partner
[Partner("Sonar", Contract = pxsonar.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExisting)]
pxsonar.SonarOperations _sonarPort = new pxsonar.SonarOperations();
pxsonar.SonarOperations _sonarNotify = new pxsonar.SonarOperations();
...
// Dentro de un Interleave tengo esto:
// Sonar update handler
Arbiter.Receive<SonarUpdate>(true, _mainPort, SonarUpdateHandler),
...
// Luego creo la suscripción:
_sonarPort.Subscribe(_sonarNotify); // Subscribe to sonar
...
// Y el manejador:
void SonarUpdateHandler(SonarUpdate update)
{
pxsonar.SonarState sonarData = update.Body;
...
}
Eso es lo que me esta dando fallo. por lo de mas lo tenemos igual. Si no podemos hacer la copia del body en el SonarState
The administrator has disabled public write access. Please, register to participate in the
forum.
avionf18
User Expert Boarder
Posts: 24
Karma: 3
Re:Intercambio de información entre Servicios - 2008/03/27 02:47Nueva conclusion el metodo Update es una clase definida paquete Microsoft.Dss.ServiceModel.Dssp que sirve para recibir la actualizaciones de los datos miembros de un servicio declarado en su apartado types.cs. En el caso del sonargenerico, se realiza una subscripcion. Definimos el puerto. Activamos el Arbiter para que este atento a la clase Update especifica para el sonar(me permito llamarla heredada). Pero como no esta. No puedo recibir la actualizaciones del Sonar en otro servicio.
PD: Perdon porque sea un poco coñazo. Es que esta cerca la primera fecha entrega
The administrator has disabled public write access. Please, register to participate in the
forum.
Raúl
Moderator Moderator
Posts: 444
Karma: 6
Re:Intercambio de información entre Servicios - 2008/03/27 16:08Eso es. Lo que yo hago es definir la clase SonarUpdate (heredando de Update) en el archivo MiServicioTypes.cs de mi servicio:
Code:
class SonarUpdate : Update<pxsonar.SonarState, PortSet<DefaultUpdateResponseType, Fault>>
{
public SonarUpdate(pxsonar.SonarState body)
: base(body)
{ }
public SonarUpdate()
{ }
}
Y SonarUpdate lo declaro como una operación del puero principal de mi servicio:
Code:
[ServicePort()]
class MiServicioOperations : PortSet<
...
SonarUpdate,
...
>
{}
[ServicePort()]
class MiServicioOperations : PortSet<
...
SonarUpdate,
...
>
{}
Pero me da un error de acesso inconsistente a la clase base. Hago un rastreo de la clase Update deriva de Iport, que es el tipo de clase que toma por parametro portSet para TResponse. Si pudieras pasarme el código de como lo implementas tal vez podría sacar conclusiones. Es algo muy raro
Post edited by: avionf18, at: 2008/03/27 20:07
Post edited by: avionf18, at: 2008/03/31 01:03
The administrator has disabled public write access. Please, register to participate in the
forum.
avionf18
User Expert Boarder
Posts: 24
Karma: 3
Re:Intercambio de información entre Servicios - 2008/04/03 02:32He pensado utilizar la operacion _SonarPort.Get. Este metodo coge el atributo body, que contiene el ansiado SonarState. Pero no se si será correcto. Pero es que me he pateado internet y no he podido encontrar ninguna solución para acceder al array de doubles. Y ya estoy muy perdido.
The administrator has disabled public write access. Please, register to participate in the
forum.
[Partner("Sonar", Contract = pxsonar.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExisting)]
pxsonar.SonarOperations _sonarPort = new pxsonar.SonarOperations();
pxsonar.SonarOperations _sonarNotify = new pxsonar.SonarOperations();
Cuando el servicio de sonar actualice su estado y lo modifique. Por lo tanto, tienes que leer el estado (el array de doubles) en el manejador correspondiente a la operación SonarUpdate:
El código anterior recoge las medidas del sonar siempre que el servicio de sonar ha notificado una actualización (update) de su estado.
Para que el manejador anterior se ejecute en estas condiciones tienes que registrarlo al iniciar tu servicio como el método que se ejecutará cada vez que tu servicio reciba una notificación de actualización del sonar, por ejemplo:
Code:
// Service main port Request Hander Setup
Activate(
Arbiter.Interleave(
new TeardownReceiverGroup(
// Default Service Drop
Arbiter.Receive<DsspDefaultDrop>(false, _mainPort, DropHandler)
),
new ExclusiveReceiverGroup(
// Sonar update handler
Arbiter.Receive<SonarUpdate>(true, _mainPort, SonarUpdateHandler),
// Drive update handler
Arbiter.Receive<DriveUpdate>(true, _mainPort, DriveUpdateHandler)
),
new ConcurrentReceiverGroup(
// Default DSS Lookup handler
Arbiter.Receive<DsspDefaultLookup>(true, _mainPort, DefaultLookupHandler)
)
)
);
Además, tienes que suscribirte al servicio de sonar:
Code:
_sonarPort.Subscribe(_sonarNotify);
Fíjate que estás escuchando en el _mainPort. Por eso tienes que añadir la clase SonarUpdate en el ServicePort de tu servicio:
Code:
class SonarUpdate : Update<pxsonar.SonarState, PortSet<DefaultUpdateResponseType, Fault>>
{
public SonarUpdate(pxsonar.SonarState body)
: base(body)
{ }
public SonarUpdate()
{ }
}
No sé por qué te falla... ¿Puedes mandarme el error exacto que te da y la parte de tu código correspondiente a esto? ¿Estás añadiendo la clase SonarUpdate al portset principal de tu servicio?Raúl Arrabales Moreno. conscious-robots.com/raul
The administrator has disabled public write access. Please, register to participate in the
forum.