-
-
Notifications
You must be signed in to change notification settings - Fork 511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add QGC Mission import capability #235
Conversation
So many errors reported in json11! We better ignore them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is certainly going in the right direction, I think!
CMakeLists.txt
Outdated
@@ -99,6 +99,7 @@ include(autogenerate_plugin_container.cmake) | |||
include_directories( | |||
include | |||
libs/include | |||
libs/json11 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put libs/json11
to the bottom of this list and put a SYSTEM
in front of it. This way the warnings are ignored.
plugins/mission/mission.cpp
Outdated
LogErr() << "Mission: Unsupported mission command: " << command; | ||
return Mission::Result::UNSUPPORTED_MISSION_CMD; | ||
} | ||
std::cout << "Cmd: " << command << " Lat: " << lat_deg << " Lon: " << lon_deg << " Alt: " << |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use LogDebug()
please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I will. Thanks.
plugins/mission/mission.cpp
Outdated
} | ||
std::cout << "Cmd: " << command << " Lat: " << lat_deg << " Lon: " << lon_deg << " Alt: " << | ||
rel_alt_deg << | ||
" Speed " << speed_m_s << " Is fly thru: " << is_fly_through << |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this print Is fly through: 1
? Or true
and false
?
You could do: << (is_fly_through ? "yes" : "no") <<
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot! I will add.
plugins/mission/mission.cpp
Outdated
} | ||
|
||
// Compose mission items | ||
Mission::Result result = [&items](const Json & mission_json) -> Mission::Result { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel this function is too big. It would be better to split it up into logic that reads the file and a parse function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even I felt the same. But we need to make them static again! Also we need to add them to mission.h
. C-style is to make them static
functions. But lets not use C-style. Isn't it ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or we can have whole implementation in MissionImpl
class. And lets invoke them via Mission
class. Does it make sense ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, move it to MissionImpl
and invoke in Mission
.
plugins/mission/mission_item.h
Outdated
@@ -87,6 +88,13 @@ class MissionItem | |||
NONE /**< @brief No action. */ | |||
}; | |||
|
|||
/** | |||
* @brief Converts CamerAction to English strings. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CamerAction
-> CameraAction
.
plugins/mission/mission_impl.cpp
Outdated
gimbal_yaw_deg = params[2]; | ||
break; | ||
case MAV_CMD_NAV_WAYPOINT: | ||
is_fly_through = (params[0] == 0.0) ? true : false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no break on purpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Because, param 5,6,7 of both NAV_WAYPOINT & NAV_TAKEOFF require Lat, Long and Alt respectively.
plugins/mission/mission_impl.cpp
Outdated
speed_m_s = params[1]; | ||
break; | ||
case MAV_CMD_DO_MOUNT_CONTROL: | ||
// Possible bug in QGroundcontrol. It stores -ve values for pitch in deg. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pitch down is -
because it's all in the NED frame.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh! Thanks @julianoes for the clarification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shakthi-prashanth-m this is looking good, however, such a piece of code really should have a unit test in my opinion.
I suggest you add an example json file and read it in and check the values. This way, when QGC changes the format, we can just update the test file and rerun it and make sure we're still compatible.
plugins/mission/mission_impl.cpp
Outdated
gimbal_yaw_deg = params[2]; | ||
break; | ||
case MAV_CMD_NAV_WAYPOINT: | ||
is_fly_through = (params[0] == 0.0) ? true : false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing break, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:) Like I said here, its intentional. Param 5,6,7 of both NAV_WAYPOINT & NAV_TAKEOFF need Lat, Long and Alt respectively, so combined them.
plugins/mission/mission_impl.cpp
Outdated
|
||
// Add mission item to the list | ||
mission_items.push_back([&]() -> std::shared_ptr<MissionItem> const { | ||
std::shared_ptr<MissionItem> new_item(new MissionItem()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of std::shared_ptr<MissionItem> new_item(new MissionItem());
you can do auto new_item = std::make_shared<MissionItem>();
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@julianoes I agree with you. How about adding integration_tests/mission_qgc.cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be a unit test in my opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, you mean as part of integration_tests/mission.cpp ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, not an integration test, a unit test.
https://github.com/dronecore/DroneCore/blob/develop/CMakeLists.txt#L221-L230
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok! Thanks. I'll add it.
plugins/mission/mission_impl.cpp
Outdated
LogWarn() << "Mission: Unsupported mission command: " << command << ". Ignoring."; | ||
break; | ||
} | ||
// Maybe removed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe what? 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant that we can remove debug log if its annoying for larger mission. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand but it's a funny comment.
CMakeLists.txt
Outdated
@@ -104,6 +104,7 @@ include_directories( | |||
${CMAKE_CURRENT_BINARY_DIR}/include | |||
${CMAKE_CURRENT_BINARY_DIR}/core | |||
SYSTEM ${additional_includes} | |||
SYSTEM libs/json11 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When #188 gets merged, I guess json11 can become a dependency of the mission plugin only, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The new functionality is good.
- This does need a unit test.
- This replaces the example showing normal use of the API with use of the QGC plan. The implication is that you don't want to show people how to use the API, you only expect them to use the QGC plan.
- IMO you either show both cases or you have a separate example for the qgc plan import.
- Personally I would revert to the previous example (but with your excellent documentation header) and either have a standalone example, or possibly just point users to the unit test - that should be enough information.
- If this is part of the example code, I'd supply a dummy plan. This will make it easier for users to play with.
@hamishwillee Thanks for your review comments.
Yes, next commit will have it.
Good observation. But we've example usage of it in integration tests. So, we don't need to show it in example.
Thanks. Sure, I would prefer to show Fly mission example with QGC import mission feature as it is user-friendly.
Plan for example code ? Please share. |
Well you're going to have examples of everything in the integration tests or unit tests, so you might argue why have any examples at all. See below ....
Example code should be designed to show off the most commonly used parts of the API or the tricky bits of the API. Essentially I think I can very easily work out how to use the QGC import function by inspection, but using the main API is more challenging. If you really think that 90% of users will be working off a QGC plan then maybe, but I doubt that is the case. I don't mind if you have both :-) Maybe @julianoes can tie break.
What I mean is that for this example the instructions would have to say "go create a plan in QGC, download it, then run our example code using this command line ...". I am proposing that you provide a pre-created QGC plan (ie not a "dummy plan", sorry for wording) so that the instructions can be something like "You can test this by using the following command line". |
OK, I understand your point @hamishwillee .
@julianoes @hamishwillee please share your opinion. Thanks |
bed6160
to
db1474f
Compare
@julianoes @hamishwillee @JonasVautherin Kindly review. Thanks. |
2524158
to
095063a
Compare
|
e84797e
to
6466535
Compare
.gitmodules
Outdated
@@ -13,3 +13,6 @@ | |||
[submodule "grpc/server/proto"] | |||
path = grpc/server/proto | |||
url = https://github.com/dronecore/DroneCore-Proto.git | |||
[submodule "plugins/mission/libs/json11"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice to have it inside the plugin :-).
How about putting it in third_party
instead of libs
? I started using third_party
because that's what they use in gRPC and many of its dependencies (maybe that's a Google convention, Idk), and I find it clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice to have it inside the plugin :-)
Yes, I placed it inside mission as it is dependency of the plugin alone.
How about putting it in third_party instead of libs? I started using third_party because that's what they use in gRPC and many of its dependencies (maybe that's a Google convention, Idk), and I find it clearer.
I see. Yeah AFAIK we have a choice: external
or third_party
. I'm not particular about it, but I see that external
is popular. What do you think ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a strong opinion on this but we should be consistent if possible. If it changes, then let me know because this is used in the docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like third_party
, firstly because there is no possible confusion for me, and also because that's the one I see in grpc, protobuf, boringssl, that are our dependencies already.
Travis CI says below error while performing Docker build for Ubuntu & Fedora.
Rest are successful. Can we ignore this ? |
Travis fails on Ubuntu and Fedora because of a style error (see last lines of the log). Regarding the update warning, IMO it is not so important for us, so we can ignore it. |
@JonasVautherin Yeah, its strange; when I ran this locally, there are no such style errors reported. |
Does the |
Yes. I ran |
15c9e75
to
f3054df
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, looks fairly correct. Does it run as part of the make run_unit_tests
?
See various inline comments.
core/CMakeLists.txt
Outdated
@@ -107,6 +107,7 @@ if(NOT IOS AND NOT ANDROID) | |||
# SYSTEM because we don't want warnings for gtest headers. | |||
include_directories(SYSTEM libs/gtest/googletest/include) | |||
include_directories(SYSTEM libs/gtest/googlemock/include) | |||
include_directories(${CMAKE_SOURCE_DIR}/core) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation
core/CMakeLists.txt
Outdated
@@ -117,7 +118,9 @@ if(NOT IOS AND NOT ANDROID) | |||
timeout_handler_test.cpp | |||
call_every_handler_test.cpp | |||
curl_test.cpp | |||
# FIXME: Below line is NOT capturing plugin unit tests sources. So adding manually. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation, make sure to switch to spaces.
using namespace std::this_thread; // for sleep_for() | ||
|
||
// FIXME: Using relative path for QGC mission plan. What's the right way ? | ||
const std::string DEFAULT_QGC_MISSION_PLAN = "../../../plugins/mission/qgroundcontrol_sample.plan"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add a sample in the example folder.
plugins/mission/mission_impl.cpp
Outdated
#endif | ||
|
||
// Add mission item to the list | ||
mission_items.push_back([&]() -> std::shared_ptr<MissionItem> const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What bugs me a little bit is that the importer does not combine the mavlink mission items together into dronecore mission items.
So, for the optimal case, a location + speed command + gimbal command would optimally end up in the same dronecore mission item. Basically, all commands following a location should be cominbed with the location.
plugins/mission/mission_impl.cpp
Outdated
case MAV_CMD_NAV_WAYPOINT: | ||
is_fly_through = (params[0] == 0.0) ? true : false; | ||
// NO break here, because params 4, 5 & 6 of both | ||
// of these commands are Lat, Lon & Alt respectively. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add // FALLTHROUGH
for GCC 7.
@julianoes Yes, it runs as part of |
Previous name is too long and unnecessary. Hence renamed to keep API name simple and effective.
Rename `Mission::import_QGC_mission()` to `Mission::import_qgroundcontrol_mission()` to maintain snake_case style.
1. Moved building unit tests to main CMakeLists.txt. 2. Renamed libs to "third_party". 3. Methods used to import mission are renamed for clarity. 4. Enum for AirSpeed, GroundSpeed are explicity intialized for protability.
Move to plugins/mission/third_party/json11
As per https://git-scm.com/docs/gitmodules#_description, "name" is the name of the submodule. Hence this commit does make sure each submodule entry abides by it.
Corrected name of submodules: mavlink and dronecore-proto.
This fixes Windows build error.
Its not necessary anymore as it is done in dronecore lib itself.
Moved QGC sample path to plugins/mission and used absolute path in unit test. Absolute path is composed to work on Windows as well.
For Debug configuration, we need to copy debug versions of DLL.
QGC sample plan is moved to "plugins/mission". Removed "-g" flag in building Fly QGC example.
CI fails to find debug version of DLLs and hence reverting changes to copy release versions of DLLs even in debug configuration.
@@ -11,6 +11,13 @@ | |||
#include "global_include.h" | |||
#include "log.h" | |||
|
|||
// To locate QGroundControl plan file during Unit test. | |||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shakthi-prashanth-m you can just use #ifdef WINDOWS
it's what we already have in the build system.
const std::string DEFAULT_QGC_MISSION_PLAN = "../qgroundcontrol_sample.plan"; | ||
std::string qgc_plan(DEFAULT_QGC_MISSION_PLAN); | ||
// Locate path of QGC Sample plan | ||
std::string qgc_plan = "../../../plugins/mission/qgroundcontrol_sample.plan"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eventually, I would duplicate the .plan file but for now that's ok.
Used `WINDOWS` macro for consistency.
04b1f61
to
84c73a7
Compare
@julianoes now ready to be merged unless @hamishwillee requests for changes. |
Thanks @shakthi-prashanth-m for the continuous fixing and improvements 😄. |
Congratulations on getting this in @shakthi-prashanth-m ! I'll *try to get associated docs updates in next week: mavlink/MAVSDK-docs#99 |
Thanks @hamishwillee . |
telemetry: remove level health check
This patch
Now, missions can be imported from QGroundControl plan file. This enables users to create plans on QGroundControl and simply import them into DroneCore applications. We use json11 library for parsing QGC plan files.
camera_action_delay_s
toloiter_time_s
in MissionItem class #249