Fix #765: Add error handling for OMPL path hard crashes and stop sign…#780
Fix #765: Add error handling for OMPL path hard crashes and stop sign…#780
Conversation
raghumanimehta
left a comment
There was a problem hiding this comment.
Good job! Need a couple of changes before I approve this!
You don't need to set any other field except sail in case of failure. Just set the said flag. The other teams handle the rest.
There was a problem hiding this comment.
Change the return type to Optional[ci.Path]. Handle this none return everywhere.
| return ci.Path(waypoints=waypoints) | ||
| except Exception as e: | ||
| self._logger.error(f"Exception occurred while getting path from OMPL: {e}") | ||
| return ci.Path() |
There was a problem hiding this comment.
return None here. It makes little sense that empty path is bad.
| msg.sail = False | ||
| else: | ||
| msg.heading.heading = desired_heading | ||
| msg.steering = 0 |
There was a problem hiding this comment.
Why's the steering 0 here?
There was a problem hiding this comment.
Also, I don't think we change steering. Confirm this, please.
raghumanimehta
left a comment
There was a problem hiding this comment.
There are other things that are missing still. Consider the scenarios:
- What happens when the boat was set to
sail == False, when would this be next checked? Have you tested this? - What happens if the
OMPLfailed becuase of other reasons? I believe we could handle this by after thesail = False, try again immediately a couple of times. If we can't get a path, wait for, let's say, 10 minutes before attempting to generate a new path.
What are your thoughts on these points? @jb3982 @SPDonaghy @FireBoyAJ24
| ) | ||
| except Exception as e: | ||
| self._logger.error(f"Failed to get new OMPL path: {e}") | ||
| return None, local_waypoint_index |
There was a problem hiding this comment.
Should perhaps return None for both.
| ) | ||
| except Exception as e: | ||
| self._logger.error(f"Failed to get old OMPL path: {e}") | ||
| return None, local_waypoint_index |
There was a problem hiding this comment.
Same as above comment.
There was a problem hiding this comment.
Also you could perhaps abstract this to a function. DRY principle
| self._ompl_path = ompl_path | ||
| self.path = self._ompl_path.get_path() | ||
| local_path = self._ompl_path.get_path() | ||
| if local_path is None: |
There was a problem hiding this comment.
You should update self.path still. You have logged the error but in the next cycle, the reference to self.path would have a valid path which is incorrect behaviour.
There was a problem hiding this comment.
self.path = local_path runs after the if block, since there is no return statement. So, won't it set the self.path to None and in this would trigger if old_ompl_path is None or self.path is None: check. where it would call self._update(omple_path)
I think this is a good idea. Could we use a shorter cooldown than 10 minutes though? Short enough so that our boat isn't drifting aimlessly for too long. What do you think is reasonable? |
Yes. No, just set it to 10 minutes for now. We can discuss this later. |


Description
This PR addresses the issue where the pathfinding node would crash when OMPL fails to compute a valid state space solution. The changes introduce error handling and a new stop signaling mechanism.
Changes made:
sailboolean field toDesiredHeadingmessage to signal when the boat should stopompl_path.get_path()to catch OMPL exceptionslocal_path.update_if_needed()for both new and old path retrievalsnode_navigate.desired_heading_callback()to detect pathfinding failures and setsail=Falsesailfield behavior and error handling in custom_interfacesREADME.mdBehavior:
DesiredHeadingis published withsail=False,heading=0.0, andsteering=0Verification
test_error_handling.py) locally and verified all tests passget_path()failsupdate_if_needed()returns(None, waypoint_index)on failuredesired_heading_callback()setssail=Falsewhen heading isNoneResources