IEEERobotics / high-level

CV, localization, mapping, planning, and generally anything that will run on the PandaBoard
BSD 2-Clause "Simplified" License
2 stars 1 forks source link

Need to block for localizer update #22

Closed dfarrell07 closed 11 years ago

dfarrell07 commented 11 years ago

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).

jschornick commented 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.

dfarrell07 commented 11 years ago

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?

jschornick commented 11 years ago

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.

dfarrell07 commented 11 years ago

Here's how I was thinking about it.

  1. nav gets a goal pose from planner.
  2. nav generates a solution, which uses bot_loc, and therefore bot_loc must be clean before this step finishes.
  3. nav sets bot_loc to stale.
  4. nav sends a move command to comm.
  5. nav feeds the comm response and sensor data to localizer.
  6. These can happen in any order:
    • localizer processes the data, either doing a full run or a quick update.
    • nav checks bot_loc before it uses it again, blocking if dirty. It could not put data in the queue before localizer finishes and sets bot_loc to clean, as that would involve checking bot_loc and blocking.
  7. localizer finishes and sets bot_loc to fresh.
  8. nav checks bot_loc and it is now fresh. It uses bot_loc for for various things.
  9. nav sets bot_loc to stale (repeating from 3)...
  10. nav issues another move command to comm (repeating from 4)...
dfarrell07 commented 11 years ago

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).

jschornick commented 11 years ago

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.

dfarrell07 commented 11 years ago

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.

dfarrell07 commented 11 years ago

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.

dfarrell07 commented 11 years ago

I think we have this figured out.