Replies: 1 comment 1 reply
-
I agree with some of the points here but would strongly prefer if BT nodes did not do any task validation. This would make them tied to hardware and potentially not reusable across deployments. I see BT nodes as building blocks that are application independent that simply perform an operation on the inputs to return an output. Most of our action nodes should just be packaging input data into ROS 2 msgs and making necessary action/service calls to get results. Here's my proposal to handle all of this:BT plugin system
Hardware registration will register BT nodes
How hardware will check capabilityWe will define two classes in
Hardware facing nodes will inherit We would get rid of the How
|
Beta Was this translation helpful? Give feedback.
-
@koonpeng originally drafted the idea below (copy pasting from elsewhere)
The Old (Current) Architecture
When the workcell orchestrator receive a
Task
, it looks at thetype
field to determine which capability is responsible for handling that task. Capabilities must call a function to register themselves as the handler for a task type. The task type also controls the behavior tree (BT) used to execute the task.Problems
Capability 2.0
The new capability system attempts the solve the problems of the old system mainly by making the dependencies between task types, BTs and capabilities to be more strict and determined. In the new system,
CapabilityGroup
is not longer needed and will be removed.Essentially, we break the link between capabilities and task types and make the information flow more straight forward. Breaking this link does make us lose some information needed by some of the features, the next few sections will go over the impact of this change and how we can workaround it.
How do we determine if a task can be performed?
In the old system, because a capability register itself as the handler for a task type, we can use that to determine which capability to check if a task can be performed and if we should fallback to the generic capability.
One way to implement that in the new system is to go through all the capabilities used in the BT and check that they can perform the task. However, this present a problem as a BT may only use a subset of the nodes registered by a capability. With the current way that
Capability::can_perform_task
is tied to the capability and not to the BT node, we cannot get a reliable answer. In the initial version of the new system, this function will be removed to keep the changes minimal, a workcell will always be able to perform a task if there is a corresponding BT. A workaround for the phase 2 POC is to have the MES node transform the task type depending on the label type needed. See the section on future plans for proposals on how we can implement this function more reliably.Capability 2.1 and beyond
How do we determine if a task can be performed?
Instead of checking if a capability can perform a task, we need to check if a BT node can perform a task. In order to do that we can implement a new type of BT node, tentatively called
BTNodeWithConstraint
. It will contain a virtual method that returns if a task can be performed.However, that is another consideration which is that sometimes whether a BT node can be performed cannot be determined only by the task data. In some cases, the input port of the node may be crucial in determining if it can be performed. For these cases, the only way to (more) reliably know if something can be performed is to dry run the BT. However, the downside is that this can be slow and since checking if a task can be performed is part of the bidding process, it may slow down the whole system.
Perhaps the better solution would be to leave the responsibility of such constraints checks to the user. We allow workcells to be launched with certain constraint keys defined in ROS params. A new
constraint
field in tasks will also be needed which lists the constraint keys required for the task. Then we simply just check that the constraint keys are met. We probably should implement something like this regardless of other solutions choosed as I can imagine some kind of deny list being very useful to users.Input ports or task data?
In general, a BT node can receive inputs during either the task data or BT input ports. Mixing these sources can hurt compatibility between capabilities and led to more confusion.
The advantage of receive inputs from task data is that it simplifies writing the BT. However, the major disadvantage of this is that the structure of the data is fixed. Take
DispenseItem
BT node for example, if it receives the item to dispense from the task data, the data must be a string, what if we want to dispense multiple items? One way around it would be to allow an array, but then it stills needs to know which element in the array to use, this could be received from a input port. However, the problem with this is that we are leaving the ability to dispense multiple items in a task up to the author of the capability, if the BT node cannot destructure an array, then there is no way to create a task that dispense multiple items.Another option would be to allow tasks to break down into sub tasks, in the first implementation, we can have a BT node that loads and run another BT depending on the sub task type, however the downside of this is that we cannot check if this sub task can be performed as this container BT node is not tied to any capability, more sophisticated solutions may involve recursively going down the list of sub tasks and discovering the capabilities used, and maybe even involve some bidding process with the sub tasks. This also ties into the future plan to unify system and workcell orchestrators.
On the other hand, we can instead standardize inputs to be received from BT ports. In order for that to work, we need to have a BT node that can destructure a yaml and expose it to the blackboard. This also allows us to break the dependency on the structure of task data, the data can be in any structure and it is up to the BT author to pass the correct field to the BT node. This also ties in to how do we determine if a task can be performed, since all of the inputs would come from BT input ports, we need to do a dry run to determine if a task can be performed.
Beta Was this translation helpful? Give feedback.
All reactions