Comments (11)
The best I can tell its this node, which has the optional start field which isn't used in that BT XML because the start is implied by the server as current_pose
if no specific start is provided. I suspect that its not even the only issue, its just the first it found. We have alot of optional input ports.
@facontidavide with Groot2's BT node index, is there a new mechanic for marking optional input ports? I couldn't find any documentation on the BT.CPP website on this
from navigation2.
Let me check this.
from navigation2.
Sooo. the problem is that in the model you specified:
<Action ID="RemovePassedGoals">
<input_port name="input_goals">Input goals to remove if passed</input_port>
<input_port name="radius">Radius tolerance on a goal to consider it passed</input_port>
<input_port name="global_frame">Global frame</input_port>
<input_port name="robot_base_frame">Robot base frame</input_port>
<output_port name="output_goals">Set of goals after removing any passed</output_port>
</Action>
But in the mentioned behavior tree:
<RemovePassedGoals input_goals="{goals}" output_goals="{goals}" radius="0.7"/>
The model doesn't contain the default value, that makes them optional.
The wird thing is that, checking the source code of class RemovePassedGoals, the port global_frame
is defined but never used.
Therefore, this line must be removed: https://github.com/ros-planning/navigation2/blob/main/nav2_behavior_tree/include/nav2_behavior_tree/plugins/action/remove_passed_goals_action.hpp#L50
Additionally, "robot_base_frame" is missing too in the XML, but seems like you alternatively read it from other sources.
The solution is to add a default value like this:
BT::InputPort<std::string>("robot_base_frame", std::string(), "Robot base frame"),
But then, deconflictPortAndParamFrame
will not work anymore, because we need to consider the empty string case too.
I can try to make Groot2 a little bit more permissive, i.e add an empty port instead of failing.
But I still suggest addressing this
from navigation2.
RemovePassedGoals is a good point - but I think they're failing on something simpler with start
optional port in ComputePathToPose, given their error message.
I can try to make Groot2 a little bit more permissive, i.e add an empty port instead of failing.
OK!
from navigation2.
😄 I focused on that because it is the first error I saw when testing myself
But the problem seems to be widespread... many ports are meant to be optional but they are not declared as optional.
The problem is NOT that Groot2 fails, the actual problem is that the BehaviorTree.CPP executor should be the one failing, to catch these issues earlier
from navigation2.
but they are not declared as optional.
How do you declare optional? I don't think that's something I was aware of a option to set. the vast majority of our ports are optional. Very, very few are required
from navigation2.
You need to use this overload: https://github.com/BehaviorTree/BehaviorTree.CPP/blob/master/include/behaviortree_cpp/basic_types.h#L407-L414
This gives a default value to the port. If the port is NOT specified in the XML, the default value will be used.
Note that getInput()
will succeed and return the default value. So, you can not use that method to determine if we are using the default.
In the case of deconflictPortAndParamFrame
, I would probably change it to
template<typename T1, typename T2>
T1 deconflictPortAndParamFrame(
rclcpp::Node::SharedPtr node,
std::string param_name,
T2 * behavior_tree_node)
{
const auto param_value = behavior_tree_node->getInput(param_name);
bool is_empty = false;
if constexpr (std::is_same_v<T1, std::string>)
{
// empty if port doesn't exist or it is an empty string
is_empty = !param_value || param_value->empty();
}
if (is_empty) {
RCLCPP_DEBUG(
node->get_logger(),
"Parameter '%s' not provided by behavior tree xml file, "
"using parameter from ros2 parameter file",
param_name.c_str());
node->get_parameter(param_name, *param_value);
return *param_value;
} else {
RCLCPP_DEBUG(
node->get_logger(),
"Parameter '%s' provided by behavior tree xml file",
param_name.c_str());
return *param_value;
}
}
from navigation2.
If instead of default, what you really want is to keep that port undefined (so... real "optional"), I may consider to implement something like:
BT::InputPort<std::string>("robot_base_frame", "Robot base frame")->optional();
or
BT::InputPortOptional<std::string>("robot_base_frame", "Robot base frame");
from navigation2.
Follow up: I am trying to be consistent with the behavior of the BT.CPP executor.
-
When the XML doesn't contain a port value,
getInput
will "only" fail. Not what I intended, but I understand from @SteveMacenski that Nav2 extensively rely on this. -
When the XML contains the name of a port that is not in the model, BT.CPP throws an exception. See here
I am changing Groot2 to be consistent with that (will be fixed in version 1.5.1), but I think you still have problem 2, for instance Spin seems to have a wrong model.
<Action ID="Spin">
<input_port name="spin_dist">Spin distance</input_port>
<input_port name="time_allowance">Allowed time for spinning</input_port>
<input_port name="server_name">Server name</input_port>
<input_port name="server_timeout">Server timeout</input_port>
<output_port name="error_code_id">Spin error code</output_port>
</Action>
But in C++
static BT::PortsList providedPorts()
{
return providedBasicPorts(
{
BT::InputPort<double>("spin_dist", 1.57, "Spin distance"),
BT::InputPort<double>("time_allowance", 10.0, "Allowed time for spinning"),
BT::InputPort<bool>("is_recovery", true, "True if recovery"),
BT::OutputPort<ActionResult::_error_code_type>(
"error_code_id", "The spin behavior error code")
});
}
from navigation2.
Version 1.5.1 was released and includes this particular fix (but others may be needed in the future).
Shall we close this issue or keep it open to follow up on this topic?
from navigation2.
How do you declare optional?
You need to use this overload
That overload involves a default value, what I mean is that they are entirely optional and when not specified they should have no value. Having the getInput()
return false
is how we detect that its not set. If there's a default value, then alot of that logic would simply fail to function properly.
This gives a default value to the port. If the port is NOT specified in the XML, the default value will be used.
That's not the behavior we want. They're not optional in the sense that if not specified, there's some viable value for it. They're optional as in there are multiple, mutually-exclusive settings going on at which if some values are not provided, that tells us which to use.
If instead of default, what you really want is to keep that port undefined (so... real "optional"), I may consider to implement something
That's more in line with what I'm thinking. Though, we have something without that working right now perfectly fine. Making things explicit is never bad, so I support that as a future improvement -- but that's not really the issue at hand that the user is reporting wrt groot handling of optional inputs
If you're saying the new groot handles, happy to close! We have some potential follow ups here on the BT.CPP side, but perhaps that's sensible in our other BT.CPPv4 thread.
Thanks! Sorry for the delay, I was in London on biz travel.
from navigation2.
Related Issues (20)
- [ERROR] [1716697697.080277840] [rviz2]: Lookup would require extrapolation into the future. Requested time 1716697697.040514 but the latest data is at time 1716697697.039929, when looking up transform from frame [laser_frame] to frame [odom]
- Laser Scan rotates with robot ------- [ERROR] [1716697697.080277840] [rviz2]: Lookup would require extrapolation into the future. Requested time 1716697697.040514 but the latest data is at time 1716697697.039929, when looking up transform from frame [laser_frame] to frame [odom] HOT 1
- [for help] action `follow_path` doesn't work (humble) HOT 7
- Changing the params file HOT 1
- Understand MPPI Critics and parameters HOT 2
- 18 bugs (UAF) in `nav2_amcl` by setting dynamic parameters HOT 6
- MPPI ARM Binaries Issue HOT 9
- velocity smoother deadband velocity as an interval HOT 10
- Remove old Gazebo stuff once new gazebo lands HOT 9
- revisit nav2_behavior_tree workarounds HOT 3
- test_decorator_speed_controller complains about not finding template specialization (but succeeds) HOT 3
- Caching SmacPlannerHybrid's dist_heuristic_lookup_table HOT 1
- Issue on Starting up Nav 2 HOT 2
- Complete Port to modern Gazebo List HOT 1
- Add in optional keepout / speed zones for example in new warehouse maps
- [AMCL] Robot pose's covariance on turns HOT 3
- Nav2 Docking: Add Option for Reversing into Dock
- Nav2 Docking: Optional Collision Checking on undocking / docking HOT 2
- Nav2 Docking: Option for Non-Charging Dock Plugin Types
- Problem with bt_navigator on Humble HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from navigation2.