Calling task operations remotely.

Dear orocos-users list,

I have the following issue, at the moment I have some trouble figuring
out how to realize a functionality of calling arbitrary operations of tasks.

So precondition is:
- there is a task named "provider" that is running and registered a the
corba nameserver
- the task has a registered operation named "testop" (which for now does
not take any parameters and returns void).
- we have a local task "localTask" which has its execution engine running.
- The argument list with correct objects of correct types is already
generated before.

So now what I want to have is a c++ function like:

void callOp(std::string taskName, std::string opName,
std::vector<RTT::base::DataSourceBase::shared_ptr> args){

RTT::TaskContext *task =
RTT::corba::TaskContextProxy::Create(taskName , false);
RTT::OperationInterfacePart *operation = nullptr;
operation = task->getOperation(opName);
operation->produce(args, localTask->engine());

// now some code that executes the operation call...
}

And and exemplary call for the test task that I have could be:
callOp("provider", "testop", args);

So at the moment it seems like I can correctly set up the operation
object, but how can I make the call actually happen now?
The produce method itself doesn't seem to execute the call. In examples
that I found, always a "OperationCaller" was used, but
here I do not know the header of the operation in advance, so I can not
use the templated versions.

Question is now, how can I execute the operation?

Regards

Elmar

Calling task operations remotely.

Hi Elmar,

your code example is almost correct. operation->produce() returns a
DataSource (a FusedMCallDataSource for local operations) that, when
evaluated, calls the operation and whose value is the result of the
operation call, if any. See below.

On Thu, Jun 2, 2016 at 5:28 PM, Elmar Berghöfer <elmar [dot] berghoefer [..] ...>
wrote:

> Dear orocos-users list,
>
> I have the following issue, at the moment I have some trouble figuring out
> how to realize a functionality of calling arbitrary operations of tasks.
>
> So precondition is:
> - there is a task named "provider" that is running and registered a the
> corba nameserver
> - the task has a registered operation named "testop" (which for now does
> not take any parameters and returns void).
> - we have a local task "localTask" which has its execution engine running.
> - The argument list with correct objects of correct types is already
> generated before.
>
> So now what I want to have is a c++ function like:
>
> void callOp(std::string taskName, std::string opName,
> std::vector<RTT::base::DataSourceBase::shared_ptr> args){
>
> RTT::TaskContext *task = RTT::corba::TaskContextProxy::Create(taskName
> , false);
> RTT::OperationInterfacePart *operation = nullptr;
> operation = task->getOperation(opName);
>

if (!operation) {
// ...
}

operation->produce(args, localTask->engine());
>

RTT::DataSourceBase::shared_ptr ds = operation->produce(args,
localTask->engine());

> // now some code that executes the operation call...
>

ds->evaluate(); // or return ds->get();

> }
>
> And and exemplary call for the test task that I have could be:
> callOp("provider", "testop", args);
>
> So at the moment it seems like I can correctly set up the operation
> object, but how can I make the call actually happen now?
> The produce method itself doesn't seem to execute the call. In examples
> that I found, always a "OperationCaller" was used, but
> here I do not know the header of the operation in advance, so I can not
> use the templated versions.
>
> Question is now, how can I execute the operation?
>

produce() and evaluate() can throw exceptions in case the argument count or
types do not match or the operation implementation throws.

It should be noted that the produce() call itself is not real-time safe as
it reserves memory for the functor and result data sources. If possible,
call produce() once and store the data source pointer, which is linked to
the args sequence and can be reused even if the values of the arguments
changed. This is what Orocos scripting uses to achieve real-time execution.

>
> Regards
>
> Elmar
>

Kind regards,
Johannes

>
> --
> Dipl.-Inform. Elmar Berghöfer
> Researcher
> Cognitive Robotics / Space Robotics
> Besuchsadresse der Nebengeschäftstelle:
> DFKI GmbH
> Robotics Innovation Center
> Robert-Hooke-Straße 5
> 28359 Bremen, Germany
> Postadresse der Hauptgeschäftsstelle Standort Bremen:
> DFKI GmbH
> Robotics Innovation Center
> Robert-Hooke-Straße 1
> 28359 Bremen, Germany
> Tel.: +49 421 178 45-4104
> Zentrale: +49 421 178 45-0
> Fax: +49 421 178 45-4150 (Faxe bitte namentlich kennzeichnen)
> E-Mail: elmar [dot] berghoefer [..] ...
> Weitere Informationen: http://www.dfki.de/robotik
> -----------------------------------------------------------------------
> Deutsches Forschungszentrum fuer Kuenstliche Intelligenz GmbH
> Firmensitz: Trippstadter Straße 122, D-67663 Kaiserslautern
> Geschaeftsfuehrung: Prof. Dr. Dr. h.c. mult. Wolfgang Wahlster
> (Vorsitzender) Dr. Walter Olthoff
> Vorsitzender des Aufsichtsrats: Prof. Dr. h.c. Hans A. Aukes
> Amtsgericht Kaiserslautern, HRB 2313
> Sitz der Gesellschaft: Kaiserslautern (HRB 2313)
> USt-Id.Nr.: DE 148646973
> Steuernummer: 19/673/0060/3
> -----------------------------------------------------------------------
>
>
>
> --
> Orocos-Users mailing list
> Orocos-Users [..] ...
> http://lists.mech.kuleuven.be/mailman/listinfo/orocos-users
>
>

Calling task operations remotely.

Hi Johannes,

thank you very much for your explanation, that indeed fills my gabs here
and works perfectly fine as intended now.

Regards

Elmar

Am 03.06.2016 um 10:45 schrieb Johannes Meyer:
> Hi Elmar,
>
> your code example is almost correct. operation->produce() returns a
> DataSource (a FusedMCallDataSource for local operations) that, when
> evaluated, calls the operation and whose value is the result of the
> operation call, if any. See below.
>
> On Thu, Jun 2, 2016 at 5:28 PM, Elmar Berghöfer
> <elmar [dot] berghoefer [..] ... <mailto:elmar [dot] berghoefer [..] ...>> wrote:
>
> Dear orocos-users list,
>
> I have the following issue, at the moment I have some trouble
> figuring out how to realize a functionality of calling arbitrary
> operations of tasks.
>
> So precondition is:
> - there is a task named "provider" that is running and registered
> a the corba nameserver
> - the task has a registered operation named "testop" (which for
> now does not take any parameters and returns void).
> - we have a local task "localTask" which has its execution engine
> running.
> - The argument list with correct objects of correct types is
> already generated before.
>
> So now what I want to have is a c++ function like:
>
> void callOp(std::string taskName, std::string opName,
> std::vector<RTT::base::DataSourceBase::shared_ptr> args){
>
> RTT::TaskContext *task =
> RTT::corba::TaskContextProxy::Create(taskName , false);
> RTT::OperationInterfacePart *operation = nullptr;
> operation = task->getOperation(opName);
>
>
> if (!operation) {
> // ...
> }
>
> operation->produce(args, localTask->engine());
>
>
> RTT::DataSourceBase::shared_ptr ds = operation->produce(args,
> localTask->engine());
>
>
> // now some code that executes the operation call...
>
>
> ds->evaluate(); // or return ds->get();
>
> }
>
> And and exemplary call for the test task that I have could be:
> callOp("provider", "testop", args);
>
> So at the moment it seems like I can correctly set up the
> operation object, but how can I make the call actually happen now?
> The produce method itself doesn't seem to execute the call. In
> examples that I found, always a "OperationCaller" was used, but
> here I do not know the header of the operation in advance, so I
> can not use the templated versions.
>
> Question is now, how can I execute the operation?
>
>
> produce() and evaluate() can throw exceptions in case the argument
> count or types do not match or the operation implementation throws.
>
> It should be noted that the produce() call itself is not real-time
> safe as it reserves memory for the functor and result data sources. If
> possible, call produce() once and store the data source pointer, which
> is linked to the args sequence and can be reused even if the values of
> the arguments changed. This is what Orocos scripting uses to achieve
> real-time execution.
>
>
>
>
> Regards
>
> Elmar
>
>
>
> Kind regards,
> Johannes
>
> [...]
>
>
>

Calling task operations remotely.

(Disclaimer: This is an alternative method, so it does not answer
directly you question)

The only thing that comes to my mind is that you call the operation with
a string where you serialize the informations (the caller should do
that), and de-serialize on the other side, thus you will need a look-up
table between functionalities and function names.

you might want to follow a structure like the one described for XML
remote procedure call

https://en.wikipedia.org/wiki/XML-RPC

Cheers, Gianni.

On 02/06/16 17:28, Elmar Berghöfer wrote:
> Dear orocos-users list,
>
> I have the following issue, at the moment I have some trouble figuring
> out how to realize a functionality of calling arbitrary operations of
> tasks.
>
> So precondition is:
> - there is a task named "provider" that is running and registered a the
> corba nameserver
> - the task has a registered operation named "testop" (which for now does
> not take any parameters and returns void).
> - we have a local task "localTask" which has its execution engine running.
> - The argument list with correct objects of correct types is already
> generated before.
>
> So now what I want to have is a c++ function like:
>
> void callOp(std::string taskName, std::string opName,
> std::vector<RTT::base::DataSourceBase::shared_ptr> args){
>
> RTT::TaskContext *task =
> RTT::corba::TaskContextProxy::Create(taskName , false);
> RTT::OperationInterfacePart *operation = nullptr;
> operation = task->getOperation(opName);
> operation->produce(args, localTask->engine());
>
> // now some code that executes the operation call...
> }
>
> And and exemplary call for the test task that I have could be:
> callOp("provider", "testop", args);
>
> So at the moment it seems like I can correctly set up the operation
> object, but how can I make the call actually happen now?
> The produce method itself doesn't seem to execute the call. In examples
> that I found, always a "OperationCaller" was used, but
> here I do not know the header of the operation in advance, so I can not
> use the templated versions.
>
> Question is now, how can I execute the operation?
>
>
> Regards
>
> Elmar
>
>
>