Closed dfarrell07 closed 11 years ago
The way I understood it from our chat was that localizer would update a shared bot_state variable (e.g. bot_state['loc_status']) which you can use to decide if bot_loc is current.
Specifically, the status should be in the 'ready' state when localizer has an empty queue and finished calculations. This could be the result of full localization or just a quick update, but the point is that localizer has processed all the information you passed through the queue and bot_loc should be correct.
When nav has a new move/sensor combination for localizer to process, it should drop it in the queue and wait for 'ready'. When localizer receives the request, localizer state should report 'localizing'/'busy'/etc until it's done. There's a small race condition here that we may need to address. If the new queue requests aren't picked up immediately by localizer, nav would see that localizer is 'ready' right before it switches to 'busy'. Something like setting a dirty flag on bot_loc might be enough.
Let me work and think on this while I code this afternoon, but lets get these components connected in some fashion tonight.
What if I just set bot_loc["dirty"] = True
before every move call to comm, then feed you the comm result and wait for you to set it to False before using bot_loc to make any calculations about where we are? Am I missing something important?
I think there's a chance of a race if you don't check (or at least guarantee) that localizer isn't running when you mark bot_loc dirty/stale. For example:
This should all be a non-issue if there is some guarantee that localizer is blocking when you set the dirty flag. However, requiring that would seem to defeat the purpose of having a queue in the first place.
Here's how I was thinking about it.
Regarding your situation - how could localizer be running while bot_loc is fresh (which seems to be the start state of your scenario)? It would take a comm response off of the queue, at which point bot_loc is already stale and I'm likely blocking or about to block, then it would localize (full or quick), then once it has a new bot_loc it would update bot_loc and set it to fresh. Only then could I issue a move command and feed a new item into qNav_loc (at which point localizer isn't running, and the start state didn't happen).
The situation only arises if we're actually using the queue as a queue, which means we could have multiple updates in it at one time. I was under the impression nav would be running a set of quick moves (and feeding the corresponding updates into the queue) while localizer is working through a full localization.
If this is not the case, it may be a nonissue. It sounds like at the very least, localizer will be working off the queue and setting the fresh flag on bot_loc. We can start with that simple logic and see if we run into a race or inconsistent behavior.
I just took out the logic for making a series of quick moves, because I thought we said that I would be doing localizer's job, since I would have to make some decision about where we are and base each move off of that assumption. Since no one knows where we are better than localizer, I thought localzer would do some number of quick updates (functionally equivalent to my quick moves), and then do a full update and force me to block when it deems it necessary.
Also, qNav_loc is still being used as a queue, just a queue of max size = 1, which is reasonable given Python's multiprocessing primitives.
I think we have this figured out.
As @jschornick and I talked about today, nav needs to do some number of steps of its solution, feed every comm feedback into the qNav_loc queue, and then get a fresh bot_loc update from localizer. It then takes that current bot_loc information and uses it to decide if it is close to the location dictated by its solution, in which case it continues with the current solution, or if it's too far off and needs to generate a new solution from the current bot_loc to the goal.
How can I wait for localizer to update bot_loc (every time I complete X solution steps) and how can I know that the value in bot_loc was just updated by localizer?
For my tests, I'm just setting bot_loc to the exact value dictated by my solution at this stage (basically what dumb localizer would do, I think).