[CORBA] - Retrieving remote methods with getMethod()

[Accidentally first sent to orocos at lists [dot] mech [dot] kuleuven [dot] be by mistake.]

Hi,

First of all, let me say that Orocos is an amazing framework.
Actually, I was looking for a framework with the following capabilities.

  • Xenomai enabled
  • CORBA object distribution
  • Dynamic object loading (preferrably via XML)

Needless to say that Orocos was the perfect match.

Right now, I have a bunch of TaskContexti's deployed with the DeploymentComponent. This all works as expected.

I then tried to export my DeployementComponent object on the network. That worked fine too and I could see my object on the TAO NameService using /usr/bin/nslist (tao-utils).
Then, I created a separated (CORBA) client which retrieves a proxy to that object using the ControlTaskProxy object. The proxy seemed to work OK since I could retrieve the list of peers (which matched the list of TaskContexts that I deployed server-side with my DeploymentComponent).

My problem is that I can't do the following:

Methodi<void(long)> m = proxy->getPeer("Processor")->methods()->getMethod<void(long)>("doSomeStuff");
m(1);

I get a "No such method" error.

It is my understanding that methods of the peers of a ControlTaskProxy are dynamically created on the client side meaning that my code should probably work. Then again, I suppose I missed something obvious.

I also did some tests on orocos-apps/examples/corba-example/SingleProcess.cxx. I modified the file as follows:

connectPorts( &local, mtask );
// Modifications - begin

        std::cout << "ExecutionPeer present: " << local.hasPeer("ExecutionPeer") << std::endl;
        std::cout << "Number of methods on Execution peers (getNames): " << local.getPeer("ExecutionPeer")->methods()->getNames().size() << endl;
        std::cout << "Number of methods on Execution peers (getMethods): " << local.getPeer("ExecutionPeer")->methods()->getMethods().size() << endl;

// Modifications - end

        TaskBrowser browser( &peer );

When I run the newly compiled eprocess, I get the following output:
ExecutionPeer present: 1
Number of methods on Execution peers (getNames): 20
Number of methods on Execution peers (getMethods): 0

What puzzles is me that the last two calls do not give the same number. Why is the second call giving me 0 methods (that would explain why I can't do a getMethod())?

Note: If I use the bin/ctaskbrowser with my NameService reference as parameter, I can access all the peers and their methods so my "base setup" seems to be working OK. My only problem is that I want to retrieve remote method references inside my code (i.e. not using TaskBrowser).

Thanks in advance for any pointers and keep up the great work with Orocos.

Viktor STARK


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

[CORBA] - Retrieving remote methods with getMethod()

Hi,

First of all, let me say that Orocos is an amazing framework.
Actually, I was looking for a framework with the following capabilities.

  • Xenomai enabled
  • CORBA object distribution
  • Dynamic object loading (preferrably via XML)

Needless to say that Orocos was the perfect match.

Right now, I have a bunch of TaskContexti's deployed with the DeploymentComponent. This all works as expected.

I then tried to export my DeployementComponent object on the network. That worked fine too and I could see my object on the TAO NameService using /usr/bin/nslist (tao-utils).
Then, I created a separated (CORBA) client which retrieves a proxy to that object using the ControlTaskProxy object. The proxy seemed to work OK since I could retrieve the list of peers (which matched the list of TaskContexts that I deployed server-side with my DeploymentComponent).

My problem is that I can't do the following:

Methodi<void(long)> m = proxy->getPeer("Processor")->methods()->getMethod<void(long)>("doSomeStuff");
m(1);

I get a "No such method" error.

It is my understanding that methods of the peers of a ControlTaskProxy are dynamically created on the client side meaning that my code should probably work. Then again, I suppose I missed something obvious.

I also did some tests on orocos-apps/examples/corba-example/SingleProcess.cxx. I modified the file as follows:

connectPorts( &local, mtask );
// Modifications - begin

        std::cout << "ExecutionPeer present: " << local.hasPeer("ExecutionPeer") << std::endl;
        std::cout << "Number of methods on Execution peers (getNames): " << local.getPeer("ExecutionPeer")->methods()->getNames().size() << endl;
        std::cout << "Number of methods on Execution peers (getMethods): " << local.getPeer("ExecutionPeer")->methods()->getMethods().size() << endl;

// Modifications - end

        TaskBrowser browser( &peer );

When I run the newly compiled eprocess, I get the following output:
ExecutionPeer present: 1
Number of methods on Execution peers (getNames): 20
Number of methods on Execution peers (getMethods): 0

What puzzles is me that the last two calls do not give the same number. Why is the second call giving me 0 methods (that would explain why I can't do a getMethod())?

Thanks in advance for any pointers and keep up the great work with Orocos.

Viktor STARK


[CORBA] - Retrieving remote methods with getMethod()

On Tuesday 26 February 2008 18:10:34 Viktor Stark wrote:
> [Accidentally first sent to orocos at lists [dot] mech [dot] kuleuven [dot] be by mistake.]

Oops, I forwarded that one to orocos-users as well...I hadn't noticed your
repost.

[...]
> My problem is that I can't do the following:
>
> Methodi<void(long)> m =
> proxy->getPeer("Processor")->methods()->getMethod<void(long)>("doSomeStuff"
>); m(1);
>
> I get a "No such method" error.

This functionality relies on a yet unfinished part of the CORBA API, but a
work-around is provided. For (about) the same functionality, you can use the
MethodC class:
<http://www.orocos.org/stable/documentation/rtt/v1.4.x/api/html/classRTT_1_1MethodC.html>
and see also rtt/tests/corba-test.cpp for examples.

MethodC m = proxy->getPeer("Processor")->methods()->create("doSomeStuff");

long arg1 = 1;
m.arg( arg1 ); // takes reference to 'arg1'
arg1 = 2;
assert( m.ready() );
m.execute(); // uses '2'.

Ok. So this works. Now for the experimental support part:

I started on writing wrapper classes which use the MethodC/CommandC behind the
scenes and lets the user use the Method<void(long)> API as usual.
The 'RemoteCommand' class was my first prototype and wraps around a CommandC.
At that time, there was little demand for CORBA, so I didn't finish it. Then
you came along :-)

So I couldn't resist. I finished the RemoteCommand and RemoteMethod
implementations, you can apply the patch in attachment on the RTT source
tree, and try it again:
cd orocos-rtt-1.4.0
patch -p0 < corba-remoting.patch
cd build; make && make install

However, I did not get 'references' (double& d) as arguments or return values
working. It will compile, but they will not work as expected. For the rest, I
unit-tested the code for local methods and CORBA methods. Both worked fine.

>
> It is my understanding that methods of the peers of a ControlTaskProxy are
> dynamically created on the client side meaning that my code should probably
> work. Then again, I suppose I missed something obvious.

The interface was recreated, but there was no (easy) means to use it yet from
C++

>
> I also did some tests on
> orocos-apps/examples/corba-example/SingleProcess.cxx. I modified the file
> as follows:
>
> connectPorts( &local, mtask );
> // Modifications - begin
> std::cout << "ExecutionPeer present: " <<
> local.hasPeer("ExecutionPeer") << std::endl; std::cout << "Number of
> methods on Execution peers (getNames): " <<
> local.getPeer("ExecutionPeer")->methods()->getNames().size() << endl;
> std::cout << "Number of methods on Execution peers (getMethods): " <<
> local.getPeer("ExecutionPeer")->methods()->getMethods().size() << endl; //
> Modifications - end
> TaskBrowser browser( &peer );
>
> When I run the newly compiled eprocess, I get the following output:
> ExecutionPeer present: 1
> Number of methods on Execution peers (getNames): 20
> Number of methods on Execution peers (getMethods): 0
>
> What puzzles is me that the last two calls do not give the same number. Why
> is the second call giving me 0 methods (that would explain why I can't do a
> getMethod())?

Yes. getNames() shows you which methods are available to the CORBA and
scripting layers, getMethods() shows you which methods are locally available
in the C++ layer. For remote objects, getMethods() will return 0. My patch
does not change these return values, but makes that the
getMethod<...>("name") function can be used for CORBA methods as well.

>
> Note: If I use the bin/ctaskbrowser with my NameService reference as
> parameter, I can access all the peers and their methods so my "base setup"
> seems to be working OK. My only problem is that I want to retrieve remote
> method references inside my code (i.e. not using TaskBrowser).
>
> Thanks in advance for any pointers and keep up the great work with Orocos.

Thanks for the positive feedback :-) I'll open a Bug report for this work.

Peter