rroche
November 8, 2023, 6:01pm
1
November 15, 2023
Join us
Discord is the easiest way to communicate over voice, video, and text. Chat, hang out, and stay close with your friends and communities.
Agenda
Community Announcement
Community Q&A
General Discussions
Community Announcement
External Flight Modes is now part of main
PX4:main
← PX4:external_modes_ros2
opened 09:16AM - 06 Dec 22 UTC
### Goal
Create a library and interface for writing ROS2 applications that cont… rol the drone. This includes high-level navigation tasks all the way down to direct actuator controls.
It goes much further than the existing offboard mode:
- the ROS2 mode behaves the same as an FMU-internal mode:
- it can provide a name that is selectable in the GCS
- it can provide its own arming checks and mode requirements
- integrated into failsafe state machine
- there are clear rules for who is controlling the drone (see mode executor below)
- it's well-defined which setpoints can be sent
- a ROS2 mode can replace an FMU-internal mode
- multiple ROS2 modes & executors can co-exist and run (up to 8 can be registered)
### Concepts
This adds a few new concepts based on existing ones:
![image](https://user-images.githubusercontent.com/281593/205868186-85db9e36-b007-4f2e-918d-6cfee659a19b.png)
**Flight Mode**
- Is passive, does not execute other modes (or commands)
- Is activated via a mode executor / user / FC
- Selects and sends setpoints to the FC (e.g. velocity)
- Has a name displayed by the GCS
- Can configure its mode requirements
**Mode Executor**
- Can select modes and send commands when it is in charge (and wait for completion)
- Selects exactly one ‘owned’ mode. This is typically a custom mode that then generates the setpoints to perform the desired task.
- The executor is in charge when the owned mode gets selected and stays in charge until failsafe is triggered or the user switches modes.
- There can be multiple executors, but at most one is in charge at any given time
- In terms of FMU implementation, the `navigator` module corresponds to the mode executor (it currently does more than that though, also implementing several modes)
- Note that this is not a recursive definition (executors cannot activate other executors)
**Config Overrides**
Both, modes and executors can define configuration overrides. Two are defined and implemented currently:
- disable auto-disarm. Allows for landing and then taking off again
- ability to defer non-essential failsafes. Allows for e.g. an executor to execute a critical action w/o being interrupted by low-battery failsafe.
**Mode Replacement**
An external mode can replace an internal one, for example a sophisticated RTL. Both triggering RTL failsafe or a user selecting RTL in the GCS will then use the external mode instead. If the external mode crashes, the internal one will be used as fallback. This is currently based on regular arming check request timeout (could later be extended to include setpoint timeouts too).
**Mode Completion**
For an executor to know when to continue, there's a new topic `mode_completed` added, published by takeoff, rtl, etc.
### Example Usage
A flight mode looks like this:
```cpp
class FlightModeTest : public ModeBase
{
public:
FlightModeTest(rclcpp::Node &node)
: ModeBase(node, Settings{"My Mode"}, ModeRequirements::manualControlledPosition())
{
setSetpointUpdateRate(60.f);
}
void checkArmingAndRunConditions(HealthAndArmingCheckReporter &reporter) override
{
// custom checks
}
void onActivate() override
{
setpoints().configureSetpointsSync({});
}
void onDeactivate() override {}
void updateSetpoint() override
{
// send setpoint
}
private:
};
```
And a mode executor in the form of a simple state machine:
```cpp
class ModeExecutorTest : public ModeExecutorBase
{
public:
ModeExecutorTest(rclcpp::Node &node, ModeBase &owned_mode)
: ModeExecutorBase(node, ModeExecutorBase::Settings{false}, owned_mode),
_node(node)
{}
enum class State {
Reset,
WaitForArming,
Arming,
TakingOff,
MyMode,
RTL,
WaitUntilDisarmed,
Shutdown,
};
void onActivate() override
{
runState(State::WaitForArming, Result::Success);
}
void onDeactivate(DeactivateReason reason) override
{}
void runState(State state, Result previous_result)
{
if (previous_result != Result::Success) {
RCLCPP_ERROR(_node.get_logger(), "State %i: previous state failed: %s", (int)state, resultToString(previous_result));
return;
}
RCLCPP_DEBUG(_node.get_logger(), "Executing state %i", (int)state);
switch (state) {
case State::Reset:
break;
case State::WaitForArming:
waitReadyToArm([this](Result result) { runState(State::Arming, result); });
break;
case State::Arming:
arm([this](Result result) { runState(State::TakingOff, result); });
break;
case State::TakingOff:
takeoff([this](Result result) { runState(State::MyMode, result); });
break;
case State::MyMode:
scheduleMode(ownedMode().id(), [this](Result result) { runState(State::RTL, result); });
break;
case State::RTL:
rtl([this](Result result) { runState(State::WaitUntilDisarmed, result); });
break;
case State::WaitUntilDisarmed:
waitUntilDisarmed([this](Result result) { runState(State::Shutdown, result); });
break;
case State::Shutdown:
rclcpp::shutdown();
break;
}
}
private:
rclcpp::Node &_node;
};
```
### Other
- Implements and depends on https://github.com/mavlink/mavlink/pull/1915
- I have some example modes if anyone is interested
- Flash usage is ~20KB, and ~8KB for flash constrained builds
### TODO's (for later)
- main missing part: control interface (defining setpoints)
- test on hw
- param handling
- move the lib into own repo, add `px4_ros_com` (the transformations)
- metadata handling for custom checks
- CI: run tests
- mode activation by command with configuration (e.g. orbit)
- log mode names
- ...
Pixhawk FMUv6XRT is also now in tree
PX4:main
← PX4:pr-px4_fmu-v6xrt
opened 05:35PM - 25 Oct 23 UTC
Replaced https://github.com/PX4/PX4-Autopilot/pull/21321
### To do's
- [x… ] USB VID and String Set
- [x] Fix CI issues
Bugs
- [x] `reboot -b` not staying in bootloader
- [x] https://github.com/PX4/PX4-Autopilot/issues/22160
Community Q&A (No deep technical discussions)
Guideline for asking a Question
Specify what you are trying to achieve
Specify what environment / platform you are using
Prepare a Link or Document to help understand if possible
First, ask the question on Discord or create a Github Issue !
If you take over 5 minutes for the question, please continue in Discord or a Github Issue.
Q1: Why is my external module failing
A1: We should implement a CICD pipeline to make sure that external modules are not broken in the future.
Modules should talk to each other through pub/sub not build off of each other. If you hit a particular problem with mavlink receiver you can lower the priority of the mavlink receiver thread. That would be a straightforward change. Or, you could do round robin scheduling with a time slice in place so that other mavlink instances have a chance to run.
Q2: tools or tips for creating a vehicle in Gazebo
A2: gazebo sim app there is a ton of models: https://app.gazebosim.org/fuel/models , you can take one of those and start to modify it from there. Here is also a really good video tutorial: https://app.gazebosim.org/fuel/models .
Q3: Auto-land for fixed wing
A3: The auto-land for 1.14 stable is broken for terrain follow. It keeps girating up and down. Terrain follow goes from valid to invalid from valid to invalid. It can be recreated in sitl.
Q4: Collision prevention cp_guide_angle does not seem to be working to yaw the vehicle before hitting an object. How can we fix it / should we rip out the logic and add something new
A4: biggest obstacle was that there is nothing in sitl that we can test with nor something easy in real life. Andrew has a branch of this working in sitl. we can utilize that branch for people to work on the collision prevention guide angle logic behind the scenes, and then test on the starling.
Hi everybody, another question for you guys.
I have an out-of-tree module and would like to include the mavlink_receiver.h
header into that said module to share a variable.
But when I follow the documentation: External Modules (Out-of-Tree) | PX4 User Guide (main) for including the platforms_common
I get this error:
Even though I’m not sure if that’s the platforms__common
dependency that I want, when I’m reading the definition of the px4_add_module
CMake function, I think that’s how I should use it, although I’m not too sure, here’s the link that talks about DEPENDS
: https://github.com/PX4/PX4-Autopilot/blob/00568985c0dd750d00eaaa53f05733e8f79714f0/cmake/px4_add_module.cmake#L66
Here’s the definition of our out of tree module CMakeLists.txt file:
And here I’d like it to be able to simply add in my file:
#include <mavlink/mavlink_receiver.h>
And use a value set there.
I hope this is clear enough don’t hesitate to ask for clarification .
Thank everybody!
Ludovic
1 Like