How to trigger a Charger search and aproach once the robot reaches a ìs_charger` location? (#222)

Posted by @TheConstructAi:

Hi,

Is there any example or explanation on how to trigger a service/action that makes the robot search and dock into a charger port, once the robot has returned to a is_charger node?

How would it be done also to trigger this call to UNdock once the battery is full and a task has been assigned to the robot?

Is the #169 the future way it will be done?
Do we have to for the moment use the Task user defined the only way?
Could we do something similar to what the clean task does? Are there examples of the cleaning trigger?

To make basically clear what I’m asking here is:

  1. I have a robot with slotcar and RMF enabled.
  2. When it finished a task or when the battery level is low enough, it will return to the closest is_charger node.
  3. Once it arrives there, SOMEHOW, we have to trigger a call to a service that starts the robot to charging dock procedure and starts charging.
  4. Once its fully charged, it should stay there charging in the dock until a task is assigned to it ( which is possible because its 100% charged).
  5. When a new task is assigned, it should call the UNdock service and start its new task after that.

Let me know what are your suggestions in this matter


Edited by @TheConstructAi at 2022-09-14T14:20:28Z

Posted by @Yadunund:

Hi there!

There are a couple of ways to get your robot to execute a special manoeuvre such as docking with its charger. One way to do this is to

  1. Assign the charging waypoint with the dock_name property using rmf_traffic_editor. Let’s assume you give it a dock_name of charger_1 for example.
  2. When your robot navigates to this charging waypoint, right before it enters the lane where the charger waypoint is the exit node, the fleet adapter will trigger the RobotCommandHandle::dock() function that was implemented as part of writing the fleet adapter. The dock_name parameter here will be the same as that defined using rmf_traffic_editor (charger_1).
  3. You should implement your fleet adapter's dock() function in such a way that once you receive a dock_name that is a charger, it will call the dock service.

We’ve followed this approach for other fleets and you can reference the implementation for the Ecobot cleaning robots here. The callback here checks if “charger” is a substring of the dock_name and if so, calls a special API to trigger the automatic docking service. For other dock_names, the API for cleaning is invoked.

For this robot, while the robot is docked and receives a command from RMF to navigate somewhere, it automatically undocks and proceeds to navigate to its goal. Hence there was no need to execute an Undock service. Is there a way your robot can do the same? Alternatively, your fleet adapter can keep track of the robot’s charging state and once it is fully charged, you call the service to Undock

The behavior of the ChargeBattery task is slightly different. There are two “phases” of this task.

  1. Navigate to the assigned charger
  2. Wait till the robot’s battery % crosses a configurable threshold.
    Only after both phases complete, is the robot considered to be done with the task (and move on to the next task).

So assuming you’ve configured the charging waypoint with a dock_name property, it will automatically call the docking service as part of Phase 1 described above.


Edited by @Yadunund at 2022-09-20T15:04:25Z

Posted by @TheConstructAi:

Great! Thanks for the insight!

In the next days I’ll be posting my tests here , in case I run into issues.

I imagine that in that configuration, the charging nodes, have to be outside the main paths, to avoid triggering the dock callback by accident, right?

As for making the robot undock automatically when it received a task… I suppose that RMF wont send any task until the robot battery is charged to the threshold determined. But the issue is that the sequence that the robot should follow is:

  1. I receive a task when I have enough battery.
  2. I execute the undock phase before moving anywhere else.
  3. Once the undock phase is done, then I start following the waypoints given by the rmf.

The question is , how could we wait for sending the first waypoint of the task until the service of the undock has finished? Becuase that is inside the task executing system right? Is there any way to do that? Becuase I imagine that the Ecobot, just ignored RMF until it had undocked, but actually rmf, shouldn’t it wait to send the robot waypoints until it has undocked? Because maybe the undock phase is very slow and gives a timeout for the RMf or something similar.

Any insight on that?

Anyways I’ll work on a demo of this and post the result here with hopes to solve this and have a better understanding of the Charging and also cleaning tasks ( which seem oddly similar)


Edited by @TheConstructAi at 2022-09-20T16:28:33Z

Posted by @mxgrey:

You can always write your fleet adapter integration code to postpone following a path when the follow_new_path command is triggered if it knows that the robot is busy in a non-interruptable action. It can finish the undocking procedure and then proceed with following the path. The RMF traffic system is very robust to delays and interruptions.

However I’ll acknowledge that the flow could be more graceful and user-friendly. It would be good to have an API that understands when this kind of action is needed and has some explicit Ack to know when the robot is ready to proceed.

maybe the undock phase is very slow and gives a timeout for the RMf or something similar.

If you postpone following a new path like I recommended above, you can avoid almost all detrimental effects of the delay by regularly updating the arrival estimate, even if the robot is not following the path yet. The more accurate your arrival estimate is, the better the system will be able to adjust to the delay.

Posted by @TheConstructAi:

Great @mxgrey , can you point an example or the code that should have to be modified? Thanks

Posted by @mxgrey:

In terms of the demo fleet adapter, one approach would be to modify these lines. Instead of starting the thread right away, that code should do something to check if the robot is busy with some action that should not be interrupted before beginning the thread.

Or perhaps a more intuitive approach would be to add another branch to the state machine in follow_new_path to check whether the robot is busy with an action, and hold off on issuing the next navigation command until the action is finished.

Posted by @TheConstructAi:

I’m having issues when implementing this , because the docking works, I get to call the service and so on but I get two behaviours that I don’t quite understand why they are happening:

  1. The first one is that immediately after calling this docking service finishes, the robot moves a bit. It happens with all the robots, even the ones using the demos version of fleet adapter. Its done regularly and Seems as is the waypoint where they stay is sent at regular intervals. Can this be deactivated somehow? Because its not very good idea having a robot docked and then turning in place.

  2. And MOST important, the docking thread doesn’t seem to get terminated or finish. At least the estimated pose in RVIZ doesn’t appear ( the yellow circle) and no other task can be assigned to that robot. So there must be something related to setting the tasks as finished that I’m missing.

Any ideas of what could this be? Whats the mechanisms to execute the dock thread and once is finished leave the robot free to do other tasks?

Here I have the Gazebo behaviour, where you can see that the teleport docking system is executed when it should, but then it returns to the docking locationwaypoint. How can that be deactivated? GAZEBO Dummy demo

And here is the RVIZ, that you can see that after a while, when this periodic waypoint sending happens, we just lost the estipated position circle, and if we send a task that is assigned to this robot, its not executed: RVIZ


Edited by @TheConstructAi at 2022-09-23T15:48:45Z

Posted by @zhangyuran-gg:

Is there a way to define a charging task?When the robot receives this task, it will return to its (dedicated) charging station for charging. And the robot can receive tasks when charging,then automatically disconnect the charging to perform the task(If in a low battery state, reject the task).
I think this should be like /rmf_demos_tasks/dispatch_go_to_place file, we can designate a robot to charge.What should I do if I want to design a /rmf_demos_tasks/go_to_charge file?
Looking forward to receiving your reply!

Posted by @TheConstructAi:

The main issue that broke the Handler was that if you use a service, it takes up the thread and meses all up, jamming the thread for ever.

I “Solved it” by just calling the service without waiting the result. I tested that both calling it in the RobotHandler or in the fleet_manager through the Fake API system like in the examples.

Hope this helps someone

Posted by @TheConstructAi:

As an update, we are trying to make this work with the development of the EasyFullControl, but the robot keeps moving to the wapoint prir to the docking waypoint.

How is it suppose to force the rmf to consider that the robot is in the ending position f the docking an NOT move it, until we undock? Any ideas?