Navigator

This is where you talk about the EV3 software itself, installation issues, and programming talk.

Moderators: roger, gloomyandy, skoehler

Re: Navigator

Postby epascual » Sat Mar 01, 2014 10:25 am

Hi Roger,

I share your vision, especially the fact that only one guy should be responsible for controlling the motors, etc. But it is more or less yet the case as far as I understood the code. Motors are driven by the pilot, and the pilot takes orders from the Navigator. So it seems an already well decomposed model.

The problem I ran into is caused by the way the listeners are wired. It is more or less equivalent to having several feeds of notification for the same action. In the scenario I found an anomaly, and for which I proposed a Q&D patch, the listeners involved in signalling the end of the move are invoked by the pilot itself as the conclusion of the Pilot.stop() method, which seems quite logical. But it happens that they are also transitively called by EV3MotorPort, when it notifies the pilot that the motor move is complete. This is IMHO where there is a flaw in the mechanism.

To be honest, although it is not untrue that listeners can be harmful (as said in the paper I referenced), the real cause is not in the listeners themselves but in the way they are "wired", which can lead to something not deterministic especially as soon as multi-threading is involved such as here.

Listeners can be handy when used at the interface between the library and the application levels. So perhaps should we replace them with a callback mechanism in all the "stock" classes to avoid out of control paths of notification. You could argue that callbacks and listeners are the same, and you would be right in a sense, but they differ in the way they are wired : callback cardinality is either 0 or 1 (0 being the NOOP callback), but listeners one is undefined (0 or more).

Using callbacks only in the library would not forbid the user to add listeners at the level (s)he needs, by sub-classing involved classes and putting listeners invocations at the callback level. This way, we should be safe on the mechanisms provided by the library side, and if things go wrong, the culprit has chances to be on the application and extensions side.


I would also mention another point, which is not related to what precedes, but since we are at thinking about how to make things better, why not taking it in account too. I've a bit disturbed by the kind of information passed to listeners (or to whatever notification mechanism we will choose). For instance, moveStarted and moveStopped notifications do not receive the same information. As expected moveStarted gets the definition of the involved move as a Move instance, which sounds fine for me. One (me at least ;)) would expect that moveStopped receives the same instance, so that both events can be correlated. Instead of this it gets a different Move instance, reflecting the current completion of the move. This can be useful too, but we miss the initial request (or something which could help to correlate). So I would suggest that all xxStopped notifications convey both initial request and current state.

Best regards

Eric
Eric PASCUAL - POBOT association VP & co-founder - http://www.pobot.org
epascual
Active User
 
Posts: 123
Joined: Sun Jan 17, 2010 12:15 am
Location: Sophia-Antipolis (France)

Re: Navigator

Postby gloomyandy » Sat Mar 01, 2014 1:38 pm

Hi,
I think Roger's point was that to some extent the listener model is used so that the navigator is updated even if some other mechanism (like direct to the pilot, or even the motors) is used to move the robot. His model makes the assumption that all movement will be via the navigator (and hence it does not need to use the listener to detect external movements). Correct me if I'm wrong Roger but that was my take on your post.

I'm not sure that using call backs instead of listeners really helps that much. The big issue with any sort of call back model is the locks and uncertainty about what the methods called by the listener will actually do (for instance they may take a long time to return). The only really safe thing to do is to call the listener on a new thread that does not hold any locks, to be totally safe you need to do this at each level (if a listener calls another set of listeners), but getting that code right can be very tricky and may lead to odd situations that may not be obvious to the called method (like for instance the call back may be delayed such that a motor has started moving again before the stop notification has been processed).

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4173
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Navigator

Postby roger » Sat Mar 01, 2014 8:32 pm

Listeners or call backs are necessary sometimes; obstacle detection is one example. But in the navigation classes can be simpler and more reliable if there are no listeners or callbacks. In my proposed model, one navigator controls the one pilot that, in turn, controls the motors. Both commands and requests for information flow from the top down.
To be consistent with this idea, there should be only one higher level object that controls the Navigator, and it can request the Navigator for information at any time. So the Navigator need not have any listeners.
But to implement this design, the Navigator and Pilot both need a separate thread to detect the moving/ stoped state of the mover.
Roger
roger
Moderator
 
Posts: 368
Joined: Fri Jun 01, 2007 4:31 am
Location: Berkeley, CA

Re: Navigator

Postby epascual » Sat Mar 01, 2014 10:55 pm

roger wrote:In my proposed model, one navigator controls the one pilot that, in turn, controls the motors. Both commands and requests for information flow from the top down.
To be consistent with this idea, there should be only one higher level object that controls the Navigator, and it can request the Navigator for information at any time. So the Navigator need not have any listeners.
But to implement this design, the Navigator and Pilot both need a separate thread to detect the moving/ stoped state of the mover.
If I understand correctly, the proposed model would work on a polled basis. Is this correct ?

If I globally agree with a "delegation" chain such as app -> Navigator -> Pilot -> Motors (which is more or less the current situation), it can happen that the app needs to request a "direct" move. In the test program I'm working on, the robot navigates between a given set of waypoints, to deposit collected objects to the right place. So I use Navigator.goTo() by passing it the appropriate waypoints. But when depositing an object, the robot needs to realize a specific motion, consisting in : open the gripper and go backwards 10cm to be far enough from the object and not hit it afterwards. This escape move cannot be ordered using waypoints, since the resulting rotation when starting the move would hit the object. The only option is thus to call the Pilot and request it this backward escape, before asking the Navigator to go to the next waypoint.

How would you see such a scenario if the app was allowed to talk only to the Navigator ? The only solution I can imagine is that the Navigator "surfaces" direct motions from the Pilot. This could be the right option, because it would still be informed of what the robot is doing, without letting something jitter in the middle of the chain.

Anyway, I agree with Andy when he mentions the fact that listeners can be a great source of trouble if the application does not implement them in a fair way and do not pay attention to their execution time. But this is more or less the same problem for interrupt handlers, and most of the programmers know how to live with them ;)

Eric
Eric PASCUAL - POBOT association VP & co-founder - http://www.pobot.org
epascual
Active User
 
Posts: 123
Joined: Sun Jan 17, 2010 12:15 am
Location: Sophia-Antipolis (France)

Re: Navigator

Postby roger » Sun Mar 02, 2014 1:31 am

Hi Eric,
I like your solution of adding the travel() and rotate)_ methods to the Navigator in so it can update the pose after each move. It preserves the delegation chain, and allows a programmer to use a Navigator without knowing anything about the Pilot.
You use the third motor for the gripper? I would like to see a picture of your bot if it is online.
Roger
roger
Moderator
 
Posts: 368
Joined: Fri Jun 01, 2007 4:31 am
Location: Berkeley, CA

Re: Navigator

Postby gloomyandy » Sun Mar 02, 2014 8:05 am

I'm not sure that polling would be required. The navigator (and pilot) internal threads can simply use the non blocking versions of the the various move operations (allowing the user code to use the non blocking version if it wants to). So no explicit polling is required. Having said that the blocking operations are often based on polling so there is not that big a difference!

Yes listeners are in many respects similar to interrupt handlers. The difference is that most systems do not expect novice programmers to write an interrupt handler! I wonder how many (even experienced) Java programmers have ever had to write one?
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4173
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Navigator

Postby lawrie » Sun Mar 02, 2014 11:09 am

Roger,

If I understand you correctly, you are arguing for going back to a model that we had in the early days of the NXT where the navigator repeated all the methods of the pilots so we could keep a strict hierarchy of control. That model was inflexible, duplicated large amounts of code and did not work for immediate return methods (when the pose did not get updated). There are many different types of navigation applications that do path finding, wall following, object avoidance, localization, mapping, slam, etc. and I don't think that model worked for many of them. Whatever, the solution is to the current problem that we have, I don't want to go back to that model.

Lawrie
lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm

Re: Navigator

Postby epascual » Sun Mar 02, 2014 11:26 am

roger wrote:I like your solution of adding the travel() and rotate)_ methods to the Navigator in so it can update the pose after each move. It preserves the delegation chain, and allows a programmer to use a Navigator without knowing anything about the Pilot.
Glad you like my suggestion ;)
roger wrote:You use the third motor for the gripper? I would like to see a picture of your bot if it is online.
It uses the 3rd motor for the gripper. The bot is strongly inspired by the Gripp3r one, having replaced the tracks by wheels (tracks introduce a severe imprecision in moves, because of the backslash at track-powered wheel joint level). It has the colour sensor in the chassis to analyse the captured object. I'll try to put a picture online... as soon as I'll have taken some.
gloomyandy wrote: Having said that the blocking operations are often based on polling so there is not that big a difference!
+1 :D

Let's say that if polling is delegated to the app, but if the lib includes also both synchronous and asynchronous versions of the commands, chances are that polling will be made twice : once at lib level to notify that the action is complete, and one at app level to test the status maintained by the lib. Maybe usage of wait/notify mechanism can be more efficient that explicit polling in app Java code, since relying on system level mechanisms.
gloomyandy wrote: I wonder how many (even experienced) Java programmers have ever had to write one?
I can't agree more :)

And you can remove the word "Java" from your sentence too, since from my own experience, the only programmers knowing something about IH are those who have written code for micro-controllers... and without using the Arduiono environment :(

The exceptions I could find are guys as old as me and who have played with ZX81, Apple ][ or any such relic of the past when they were young :)
Eric PASCUAL - POBOT association VP & co-founder - http://www.pobot.org
epascual
Active User
 
Posts: 123
Joined: Sun Jan 17, 2010 12:15 am
Location: Sophia-Antipolis (France)

Re: Navigator

Postby lawrie » Sun Mar 02, 2014 11:44 am

I am finding this thread difficult to follow as it seems to be partly abut a specific problem with the navigator, partly a proposal to completely change the model for our navigation code, and partly a discussion about the advantages and disadvantages of various design patterns. I would like to see these discussions separated out. If people want to propose a new model for navigation, I would like to see a complete proposal so we can see what types of applications it works for and what ones it doesn't work for. I think this would be a bigger change than the sensor framework as there is so much code that relies on the current model including the localization, mapping, path finding and object detection packages.

I would like to understand what the current problem is and whether it can be solved without such a sweeping change to our navigation code. I was about to start investigating it and Eric's proposed solution, but it is hard to separate this out from the rest of the thread.

On the discussion of better design patterns, I am particularly interested in better ways of implementing the current API, but they need to be complete solutions, and work for the immediate return cases.If someone has a proposal for that, I would like to hear it.

Perhaps we should start three separate threads for these three separate issues, or move some of them to the developers list. Or we could start a separate design forum.

Lawrie
lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm

Re: Navigator

Postby epascual » Sun Mar 02, 2014 11:59 am

Hi Lawrie,

I can understand your concern, and feel a bit guilty from having contributed to the flood :(

Sorry for that, from the starting point of a problem encountered while experimenting the discussion has drifted to a quite passionate debate about design. Your suggestion to split the topic, or use another support is right. But IMHO this should be kept public and not limited to the developers list for instance, since it can be interesting for people like me, who are curious about the inners of leJOS, but are not currently involved in its development.

Just my $0.02

Eric
Eric PASCUAL - POBOT association VP & co-founder - http://www.pobot.org
epascual
Active User
 
Posts: 123
Joined: Sun Jan 17, 2010 12:15 am
Location: Sophia-Antipolis (France)

Re: Navigator

Postby lawrie » Sun Mar 02, 2014 12:14 pm

Hi Eric,

I think all the discussions are good, it is just having not followed this every day, I am having difficult separating out all the different proposals here and think we need to be more focused if we are to make progress. The navigation code has not been tested much on the EV3 yet, as before Andy's changes at 0.6.0, the motor code was not stable enough.

Do you have a set of changes that fix the current Navigator problem that I can apply? I was not clear from the thread whether just removing synchronization from getTachoCount solved it.

Lawrie
lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm

Re: Navigator

Postby lawrie » Sun Mar 02, 2014 12:18 pm

I think a design forum (e.g. EV3 Design) is probably the best way to go for these discussions. Then anyone who is interested can contribute, but we can keep it separate from bugs, queries etc. We have discussed this before.

Andy, Could you (or another admin) set up a forum for this?

Lawrie
lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm

Re: Navigator

Postby epascual » Sun Mar 02, 2014 12:28 pm

lawrie wrote:Do you have a set of changes that fix the current Navigator problem that I can apply? I was not clear from the thread whether just removing synchronization from getTachoCount solved it.
The removal of the getTachoCount synchronization suggested by Andy seems to have removed the lock, as far as I have experimented until now.

The patch I proposed to remove the double trigger of the listener does its job too. But I consider it more as a workaround than as a real fix, since similar problems should still be around in other places.

I'm now investigating an intermittent misbehaviour of the Navigator when using arc moves, which makes the robot not being at the right location (although it thinks it is) after a couple of moves. It looks like some path calculation problem, but I cannot yet confirm this. The difficulty here is that it is hard to reproduce since the exact same test scenario does not always give the same behaviour. I've added traces here and there but need more time to exploit them.

Eric
Eric PASCUAL - POBOT association VP & co-founder - http://www.pobot.org
epascual
Active User
 
Posts: 123
Joined: Sun Jan 17, 2010 12:15 am
Location: Sophia-Antipolis (France)

Re: Navigator

Postby lawrie » Sun Mar 02, 2014 12:56 pm

Are you saying that both your solution and Andy's appeared to work?

It looks as if I should remove the synchronization from getTachoCount. Which version of getTachoCount is it? Is it the one in the EV3MotorRegulatorKernelModule in EV3MotorPort.java?

Andy, Can you conform that this is worth trying, even if it is not a complete solution?
lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm

Re: Navigator

Postby epascual » Sun Mar 02, 2014 1:12 pm

lawrie wrote:Are you saying that both your solution and Andy's appeared to work?
They seem too, although I'm not sure my hack could be considered as a valid solution.
lawrie wrote:Which version of getTachoCount is it? Is it the one in the EV3MotorRegulatorKernelModule in EV3MotorPort.java?
Yes.
Eric PASCUAL - POBOT association VP & co-founder - http://www.pobot.org
epascual
Active User
 
Posts: 123
Joined: Sun Jan 17, 2010 12:15 am
Location: Sophia-Antipolis (France)

PreviousNext

Return to EV3 Software

Who is online

Users browsing this forum: No registered users and 1 guest

more stuff