• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mavlink / MAVSDK / 11028673268

25 Sep 2024 07:50AM UTC coverage: 38.02% (-0.06%) from 38.077%
11028673268

Pull #2404

github

web-flow
Merge 9db1641d8 into ae4379225
Pull Request #2404: added functionality to download geofences and rallypoints

0 of 52 new or added lines in 2 files covered. (0.0%)

4 existing lines in 3 files now uncovered.

11462 of 30147 relevant lines covered (38.02%)

264.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

33.87
/src/mavsdk/plugins/mission_raw/mission_raw_impl.cpp
1
#include "mission_raw_impl.h"
2
#include "mission_import.h"
3
#include "system.h"
4
#include "callback_list.tpp"
5

6
#include <fstream> // for `std::ifstream`
7
#include <sstream> // for `std::stringstream`
8

9
namespace mavsdk {
10

11
template class CallbackList<MissionRaw::MissionProgress>;
12
template class CallbackList<bool>;
13

14
// This is an empty item that can be sent to ArduPilot to mimic clearing of mission.
15
constexpr MissionRaw::MissionItem empty_item{0, 3, 16, 1};
16

17
MissionRawImpl::MissionRawImpl(System& system) : PluginImplBase(system)
×
18
{
19
    _system_impl->register_plugin(this);
×
20
}
×
21

22
MissionRawImpl::MissionRawImpl(std::shared_ptr<System> system) : PluginImplBase(std::move(system))
1✔
23
{
24
    _system_impl->register_plugin(this);
1✔
25
}
1✔
26

27
MissionRawImpl::~MissionRawImpl()
1✔
28
{
29
    _system_impl->unregister_plugin(this);
1✔
30
}
1✔
31

32
void MissionRawImpl::init()
1✔
33
{
34
    _system_impl->register_mavlink_message_handler(
1✔
35
        MAVLINK_MSG_ID_MISSION_ACK,
36
        [this](const mavlink_message_t& message) { process_mission_ack(message); },
1✔
37
        this);
38

39
    _system_impl->register_mavlink_message_handler(
1✔
40
        MAVLINK_MSG_ID_MISSION_CURRENT,
41
        [this](const mavlink_message_t& message) { process_mission_current(message); },
1✔
42
        this);
43

44
    _system_impl->register_mavlink_message_handler(
1✔
45
        MAVLINK_MSG_ID_MISSION_ITEM_REACHED,
46
        [this](const mavlink_message_t& message) { process_mission_item_reached(message); },
×
47
        this);
48
}
1✔
49

50
void MissionRawImpl::enable() {}
1✔
51

52
void MissionRawImpl::disable()
1✔
53
{
54
    reset_mission_progress();
1✔
55
}
1✔
56

57
void MissionRawImpl::deinit()
1✔
58
{
59
    _system_impl->unregister_all_mavlink_message_handlers(this);
1✔
60
}
1✔
61

62
void MissionRawImpl::reset_mission_progress()
2✔
63
{
64
    std::lock_guard<std::mutex> lock(_mission_progress.mutex);
2✔
65
    _mission_progress.last.current = -1;
2✔
66
    _mission_progress.last.total = -1;
2✔
67
    _mission_progress.last_reported.current = -1;
2✔
68
    _mission_progress.last_reported.total = -1;
2✔
69
    _mission_progress.last_reached = -1;
2✔
70
}
2✔
71

72
void MissionRawImpl::process_mission_ack(const mavlink_message_t& message)
1✔
73
{
74
    mavlink_mission_ack_t mission_ack;
1✔
75
    mavlink_msg_mission_ack_decode(&message, &mission_ack);
1✔
76

77
    if (mission_ack.type != MAV_MISSION_ACCEPTED ||
1✔
78
        mission_ack.mission_type != MAV_MISSION_TYPE_MISSION) {
1✔
79
        return;
×
80
    }
81

82
    // We assume that if the vehicle sends an ACCEPTED ack, we might have received
83
    // a new mission. In that case we can notify our user.
84
    // However, with the (opaque) mission_id, we can determine this properly using
85
    // the id. Therefore, we only do the notification if the opaque ID is 0 and
86
    // therefore not yet supported. This way we stay backwards compatible with
87
    // previous autopilot versions.
88
    if (mission_ack.opaque_id == 0) {
1✔
89
        std::lock_guard<std::mutex> lock(_mission_changed.mutex);
2✔
90
        _mission_changed.callbacks.queue(
1✔
91
            true, [this](const auto& func) { _system_impl->call_user_callback(func); });
×
92
    }
93
}
94

95
void MissionRawImpl::process_mission_current(const mavlink_message_t& message)
1✔
96
{
97
    mavlink_mission_current_t mission_current;
1✔
98
    mavlink_msg_mission_current_decode(&message, &mission_current);
1✔
99

100
    {
101
        std::lock_guard<std::mutex> lock(_mission_progress.mutex);
2✔
102

103
        // When the last waypoint is reached mission_current_seq does not increase
104
        // so we need to ignore that case.
105
        if (mission_current.seq != _mission_progress.last_reached) {
1✔
106
            _mission_progress.last.current = mission_current.seq;
1✔
107
        }
108
    }
109
    {
110
        std::lock_guard<std::mutex> lock(_mission_changed.mutex);
2✔
111
        if (_mission_changed.last_mission_id != mission_current.mission_id) {
1✔
112
            _mission_changed.last_mission_id = mission_current.mission_id;
×
113

114
            _mission_changed.callbacks.queue(
×
115
                true, [this](const auto& func) { _system_impl->call_user_callback(func); });
×
116
            LogDebug() << "Mission changed";
×
117
        }
118
    }
119

120
    report_progress_current();
1✔
121
}
1✔
122

123
void MissionRawImpl::process_mission_item_reached(const mavlink_message_t& message)
×
124
{
125
    mavlink_mission_item_reached_t mission_item_reached;
×
126
    mavlink_msg_mission_item_reached_decode(&message, &mission_item_reached);
×
127

128
    {
129
        std::lock_guard<std::mutex> lock(_mission_progress.mutex);
×
130
        _mission_progress.last.current = mission_item_reached.seq + 1;
×
131
        _mission_progress.last_reached = mission_item_reached.seq;
×
132
    }
133

134
    report_progress_current();
×
135
}
×
136

137
MissionRaw::Result MissionRawImpl::upload_mission_items(
1✔
138
    std::vector<MissionRaw::MissionItem> mission_items, uint8_t type)
139
{
140
    auto prom = std::promise<MissionRaw::Result>();
2✔
141
    auto fut = prom.get_future();
2✔
142

143
    upload_mission_items_async(
1✔
144
        mission_items, type, [&prom](MissionRaw::Result result) { prom.set_value(result); });
1✔
145
    return fut.get();
1✔
146
}
147

148
void MissionRawImpl::upload_mission_items_async(
1✔
149
    const std::vector<MissionRaw::MissionItem>& mission_raw,
150
    uint8_t type,
151
    const MissionRaw::ResultCallback& callback)
152
{
153
    auto work_item = _last_upload.lock();
1✔
154
    if (work_item && !work_item->is_done()) {
1✔
155
        _system_impl->call_user_callback([callback]() {
×
156
            if (callback) {
157
                callback(MissionRaw::Result::Busy);
158
            }
159
        });
160
        return;
×
161
    }
162

163
    reset_mission_progress();
1✔
164

165
    const auto int_items = convert_to_int_items(mission_raw);
2✔
166

167
    _last_upload = _system_impl->mission_transfer_client().upload_items_async(
3✔
168
        type,
169
        _system_impl->get_system_id(),
1✔
170
        int_items,
171
        [this, callback, int_items](MavlinkMissionTransferClient::Result result) {
3✔
172
            auto converted_result = convert_result(result);
1✔
173
            auto converted_items = convert_items(int_items);
2✔
174
            _system_impl->call_user_callback([callback, converted_result, converted_items]() {
2✔
175
                if (callback) {
176
                    callback(converted_result);
177
                }
178
            });
179
        });
1✔
180
}
181

182
MissionRaw::Result
183
MissionRawImpl::upload_mission(std::vector<MissionRaw::MissionItem> mission_items)
1✔
184
{
185
    return upload_mission_items(mission_items, MAV_MISSION_TYPE_MISSION);
1✔
186
}
187

188
void MissionRawImpl::upload_mission_async(
×
189
    const std::vector<MissionRaw::MissionItem>& mission_raw,
190
    const MissionRaw::ResultCallback& callback)
191
{
192
    upload_mission_items_async(mission_raw, MAV_MISSION_TYPE_MISSION, callback);
×
193
}
×
194

195
MissionRaw::Result
196
MissionRawImpl::upload_geofence(std::vector<MissionRaw::MissionItem> mission_items)
×
197
{
198
    return upload_mission_items(mission_items, MAV_MISSION_TYPE_FENCE);
×
199
}
200

201
void MissionRawImpl::upload_geofence_async(
×
202
    const std::vector<MissionRaw::MissionItem>& mission_raw,
203
    const MissionRaw::ResultCallback& callback)
204
{
205
    upload_mission_items_async(mission_raw, MAV_MISSION_TYPE_FENCE, callback);
×
206
}
×
207

208
MissionRaw::Result
209
MissionRawImpl::upload_rally_points(std::vector<MissionRaw::MissionItem> mission_items)
×
210
{
211
    return upload_mission_items(mission_items, MAV_MISSION_TYPE_RALLY);
×
212
}
213

214
void MissionRawImpl::upload_rally_points_async(
×
215
    const std::vector<MissionRaw::MissionItem>& mission_raw,
216
    const MissionRaw::ResultCallback& callback)
217
{
218
    upload_mission_items_async(mission_raw, MAV_MISSION_TYPE_RALLY, callback);
×
219
}
×
220

221
MissionRaw::Result MissionRawImpl::cancel_mission_upload()
×
222
{
223
    auto ptr = _last_upload.lock();
×
224
    if (ptr) {
×
225
        ptr->cancel();
×
226
        return MissionRaw::Result::Success;
×
227
    } else {
228
        return MissionRaw::Result::Error;
×
229
    }
230
}
231

232
std::pair<MissionRaw::Result, std::vector<MissionRaw::MissionItem>>
233
MissionRawImpl::download_mission()
×
234
{
235
    auto prom = std::promise<std::pair<MissionRaw::Result, std::vector<MissionRaw::MissionItem>>>();
×
236
    auto fut = prom.get_future();
×
237

238
    download_mission_async(
×
239
        [&prom](MissionRaw::Result result, std::vector<MissionRaw::MissionItem> mission_items) {
×
240
            prom.set_value(std::make_pair<>(result, mission_items));
×
241
        });
×
242
    return fut.get();
×
243
}
244

NEW
245
std::pair<MissionRaw::Result, std::vector<MissionRaw::MissionItem> > MissionRawImpl::download_geofence()
×
246
{
NEW
247
    auto prom = std::promise<std::pair<MissionRaw::Result, std::vector<MissionRaw::MissionItem>>>();
×
NEW
248
    auto fut = prom.get_future();
×
249

NEW
250
    download_geofence_async(
×
NEW
251
        [&prom](MissionRaw::Result result, std::vector<MissionRaw::MissionItem> geofence) {
×
NEW
252
            prom.set_value(std::make_pair<>(result, geofence));
×
NEW
253
        });
×
NEW
254
    return fut.get();
×
255
}
256

NEW
257
std::pair<MissionRaw::Result, std::vector<MissionRaw::MissionItem> > MissionRawImpl::download_rallypoints()
×
258
{
NEW
259
    auto prom = std::promise<std::pair<MissionRaw::Result, std::vector<MissionRaw::MissionItem>>>();
×
NEW
260
    auto fut = prom.get_future();
×
261

NEW
262
    download_rallypoints_async(
×
NEW
263
        [&prom](MissionRaw::Result result, std::vector<MissionRaw::MissionItem> rallypoints) {
×
NEW
264
            prom.set_value(std::make_pair<>(result, rallypoints));
×
NEW
265
        });
×
NEW
266
    return fut.get();
×
267
}
268

UNCOV
269
void MissionRawImpl::download_mission_async(const MissionRaw::DownloadMissionCallback& callback)
×
270
{
271
    auto work_item = _last_download.lock();
×
272
    if (work_item && !work_item->is_done()) {
×
273
        _system_impl->call_user_callback([callback]() {
×
274
            if (callback) {
275
                std::vector<MissionRaw::MissionItem> empty_items;
276
                callback(MissionRaw::Result::Busy, empty_items);
277
            }
278
        });
279
        return;
×
280
    }
281

282
    _last_download = _system_impl->mission_transfer_client().download_items_async(
×
283
        MAV_MISSION_TYPE_MISSION,
284
        _system_impl->get_system_id(),
×
285
        [this, callback](
×
286
            MavlinkMissionTransferClient::Result result,
287
            std::vector<MavlinkMissionTransferClient::ItemInt> items) {
×
288
            auto converted_result = convert_result(result);
×
289
            auto converted_items = convert_items(items);
×
290
            _system_impl->call_user_callback([callback, converted_result, converted_items]() {
×
291
                callback(converted_result, converted_items);
292
            });
293
        });
×
294
}
295

NEW
296
void MissionRawImpl::download_geofence_async(const MissionRaw::DownloadMissionCallback &callback)
×
297
{
NEW
298
    auto work_item = _last_download.lock();
×
NEW
299
    if (work_item && !work_item->is_done()) {
×
NEW
300
        _system_impl->call_user_callback([callback]() {
×
301
            if (callback) {
302
                std::vector<MissionRaw::MissionItem> empty_items;
303
                callback(MissionRaw::Result::Busy, empty_items);
304
            }
305
        });
NEW
306
        return;
×
307
    }
308

NEW
309
    _last_download = _system_impl->mission_transfer_client().download_items_async(
×
310
        MAV_MISSION_TYPE_FENCE,
NEW
311
        _system_impl->get_system_id(),
×
NEW
312
        [this, callback](
×
313
            MavlinkMissionTransferClient::Result result,
NEW
314
            std::vector<MavlinkMissionTransferClient::ItemInt> items) {
×
NEW
315
            auto converted_result = convert_result(result);
×
NEW
316
            auto converted_items = convert_items(items);
×
NEW
317
            _system_impl->call_user_callback([callback, converted_result, converted_items]() {
×
318
                callback(converted_result, converted_items);
319
            });
NEW
320
        });
×
321
}
322

NEW
323
void MissionRawImpl::download_rallypoints_async(const MissionRaw::DownloadMissionCallback &callback)
×
324
{
NEW
325
    auto work_item = _last_download.lock();
×
NEW
326
    if (work_item && !work_item->is_done()) {
×
NEW
327
        _system_impl->call_user_callback([callback]() {
×
328
            if (callback) {
329
                std::vector<MissionRaw::MissionItem> empty_items;
330
                callback(MissionRaw::Result::Busy, empty_items);
331
            }
332
        });
NEW
333
        return;
×
334
    }
335

NEW
336
    _last_download = _system_impl->mission_transfer_client().download_items_async(
×
337
        MAV_MISSION_TYPE_RALLY,
NEW
338
        _system_impl->get_system_id(),
×
NEW
339
        [this, callback](
×
340
            MavlinkMissionTransferClient::Result result,
NEW
341
            std::vector<MavlinkMissionTransferClient::ItemInt> items) {
×
NEW
342
            auto converted_result = convert_result(result);
×
NEW
343
            auto converted_items = convert_items(items);
×
NEW
344
            _system_impl->call_user_callback([callback, converted_result, converted_items]() {
×
345
                callback(converted_result, converted_items);
346
            });
NEW
347
        });
×
348
}
349

UNCOV
350
MissionRaw::Result MissionRawImpl::cancel_mission_download()
×
351
{
352
    auto ptr = _last_download.lock();
×
353
    if (ptr) {
×
354
        ptr->cancel();
×
355
        return MissionRaw::Result::Success;
×
356
    } else {
357
        return MissionRaw::Result::Error;
×
358
    }
359
}
360

361
MavlinkMissionTransferClient::ItemInt
362
MissionRawImpl::convert_mission_raw(const MissionRaw::MissionItem transfer_mission_raw)
6✔
363
{
364
    MavlinkMissionTransferClient::ItemInt new_item_int;
365

366
    new_item_int.seq = transfer_mission_raw.seq;
6✔
367
    new_item_int.frame = transfer_mission_raw.frame;
6✔
368
    new_item_int.command = transfer_mission_raw.command;
6✔
369
    new_item_int.current = transfer_mission_raw.current;
6✔
370
    new_item_int.autocontinue = transfer_mission_raw.autocontinue;
6✔
371
    new_item_int.param1 = transfer_mission_raw.param1;
6✔
372
    new_item_int.param2 = transfer_mission_raw.param2;
6✔
373
    new_item_int.param3 = transfer_mission_raw.param3;
6✔
374
    new_item_int.param4 = transfer_mission_raw.param4;
6✔
375
    new_item_int.x = transfer_mission_raw.x;
6✔
376
    new_item_int.y = transfer_mission_raw.y;
6✔
377
    new_item_int.z = transfer_mission_raw.z;
6✔
378
    new_item_int.mission_type = transfer_mission_raw.mission_type;
6✔
379

380
    return new_item_int;
6✔
381
}
382

383
std::vector<MavlinkMissionTransferClient::ItemInt>
384
MissionRawImpl::convert_to_int_items(const std::vector<MissionRaw::MissionItem>& mission_raw)
1✔
385
{
386
    std::vector<MavlinkMissionTransferClient::ItemInt> int_items;
1✔
387

388
    for (const auto& item : mission_raw) {
7✔
389
        int_items.push_back(convert_mission_raw(item));
6✔
390
    }
391

392
    std::lock_guard<std::mutex> lock(_mission_progress.mutex);
2✔
393
    _mission_progress.last.total = int_items.size();
1✔
394

395
    return int_items;
1✔
396
}
397

398
MissionRaw::MissionItem
399
MissionRawImpl::convert_item(const MavlinkMissionTransferClient::ItemInt& transfer_item)
6✔
400
{
401
    MissionRaw::MissionItem new_item;
6✔
402

403
    new_item.seq = transfer_item.seq;
6✔
404
    new_item.frame = transfer_item.frame;
6✔
405
    new_item.command = transfer_item.command;
6✔
406
    new_item.current = transfer_item.current;
6✔
407
    new_item.autocontinue = transfer_item.autocontinue;
6✔
408
    new_item.param1 = transfer_item.param1;
6✔
409
    new_item.param2 = transfer_item.param2;
6✔
410
    new_item.param3 = transfer_item.param3;
6✔
411
    new_item.param4 = transfer_item.param4;
6✔
412
    new_item.x = transfer_item.x;
6✔
413
    new_item.y = transfer_item.y;
6✔
414
    new_item.z = transfer_item.z;
6✔
415
    new_item.mission_type = transfer_item.mission_type;
6✔
416

417
    return new_item;
6✔
418
}
419

420
std::vector<MissionRaw::MissionItem> MissionRawImpl::convert_items(
1✔
421
    const std::vector<MavlinkMissionTransferClient::ItemInt>& transfer_items)
422
{
423
    std::vector<MissionRaw::MissionItem> new_items;
1✔
424
    new_items.reserve(transfer_items.size());
1✔
425

426
    for (const auto& transfer_item : transfer_items) {
7✔
427
        new_items.push_back(convert_item(transfer_item));
6✔
428
    }
429

430
    std::lock_guard<std::mutex> lock(_mission_progress.mutex);
2✔
431
    _mission_progress.last.total = new_items.size();
1✔
432

433
    return new_items;
1✔
434
}
435

436
MissionRaw::Result MissionRawImpl::start_mission()
×
437
{
438
    auto prom = std::promise<MissionRaw::Result>();
×
439
    auto fut = prom.get_future();
×
440

441
    start_mission_async([&prom](MissionRaw::Result result) { prom.set_value(result); });
×
442
    return fut.get();
×
443
}
444

445
void MissionRawImpl::start_mission_async(const MissionRaw::ResultCallback& callback)
×
446
{
447
    _system_impl->set_flight_mode_async(
×
448
        FlightMode::Mission, [this, callback](MavlinkCommandSender::Result result, float) {
×
449
            report_flight_mode_change(callback, result);
×
450
        });
×
451
}
×
452

453
MissionRaw::Result MissionRawImpl::pause_mission()
×
454
{
455
    auto prom = std::promise<MissionRaw::Result>();
×
456
    auto fut = prom.get_future();
×
457

458
    pause_mission_async([&prom](MissionRaw::Result result) { prom.set_value(result); });
×
459
    return fut.get();
×
460
}
461

462
void MissionRawImpl::pause_mission_async(const MissionRaw::ResultCallback& callback)
×
463
{
464
    _system_impl->set_flight_mode_async(
×
465
        FlightMode::Hold, [this, callback](MavlinkCommandSender::Result result, float) {
×
466
            report_flight_mode_change(callback, result);
×
467
        });
×
468
}
×
469

470
void MissionRawImpl::report_flight_mode_change(
×
471
    MissionRaw::ResultCallback callback, MavlinkCommandSender::Result result)
472
{
473
    if (!callback) {
×
474
        return;
×
475
    }
476

477
    _system_impl->call_user_callback(
×
478
        [callback, result]() { callback(command_result_to_mission_result(result)); });
479
}
480

481
MissionRaw::Result
482
MissionRawImpl::command_result_to_mission_result(MavlinkCommandSender::Result result)
×
483
{
484
    switch (result) {
×
485
        case MavlinkCommandSender::Result::Success:
×
486
            return MissionRaw::Result::Success;
×
487
        case MavlinkCommandSender::Result::NoSystem:
×
488
            return MissionRaw::Result::NoSystem;
×
489
        case MavlinkCommandSender::Result::ConnectionError:
×
490
            return MissionRaw::Result::Error;
×
491
        case MavlinkCommandSender::Result::Busy:
×
492
            return MissionRaw::Result::Busy;
×
493
        case MavlinkCommandSender::Result::Denied:
×
494
            // FALLTHROUGH
495
        case MavlinkCommandSender::Result::TemporarilyRejected:
496
            return MissionRaw::Result::Denied;
×
497
        case MavlinkCommandSender::Result::Timeout:
×
498
            return MissionRaw::Result::Timeout;
×
499
        case MavlinkCommandSender::Result::InProgress:
×
500
            return MissionRaw::Result::Busy;
×
501
        case MavlinkCommandSender::Result::UnknownError:
×
502
            return MissionRaw::Result::Unknown;
×
503
        default:
×
504
            return MissionRaw::Result::Unknown;
×
505
    }
506
}
507

508
MissionRaw::Result MissionRawImpl::clear_mission()
×
509
{
510
    auto prom = std::promise<MissionRaw::Result>();
×
511
    auto fut = prom.get_future();
×
512

513
    clear_mission_async([&prom](MissionRaw::Result result) { prom.set_value(result); });
×
514
    return fut.get();
×
515
}
516

517
void MissionRawImpl::clear_mission_async(const MissionRaw::ResultCallback& callback)
×
518
{
519
    reset_mission_progress();
×
520

521
    // For ArduPilot to clear a mission we need to upload an empty mission.
522
    if (_system_impl->autopilot() == Autopilot::ArduPilot) {
×
523
        std::vector<MissionRaw::MissionItem> mission_items{empty_item};
×
524
        upload_mission_async(mission_items, callback);
×
525
    } else {
526
        _system_impl->mission_transfer_client().clear_items_async(
×
527
            MAV_MISSION_TYPE_MISSION,
528
            _system_impl->get_system_id(),
×
529
            [this, callback](MavlinkMissionTransferClient::Result result) {
×
530
                auto converted_result = convert_result(result);
×
531
                _system_impl->call_user_callback([callback, converted_result]() {
×
532
                    if (callback) {
533
                        callback(converted_result);
534
                    }
535
                });
536
            });
×
537
    }
538
}
×
539

540
MissionRaw::Result MissionRawImpl::set_current_mission_item(int index)
×
541
{
542
    auto prom = std::promise<MissionRaw::Result>();
×
543
    auto fut = prom.get_future();
×
544

545
    set_current_mission_item_async(
×
546
        index, [&prom](MissionRaw::Result result) { prom.set_value(result); });
×
547
    return fut.get();
×
548
}
549

550
void MissionRawImpl::set_current_mission_item_async(
×
551
    int index, const MissionRaw::ResultCallback& callback)
552
{
553
    if (index < 0 || index >= _mission_progress.last.total) {
×
554
        _system_impl->call_user_callback([callback]() {
×
555
            if (callback) {
556
                callback(MissionRaw::Result::InvalidArgument);
557
                return;
558
            }
559
        });
560
    }
561

562
    _system_impl->mission_transfer_client().set_current_item_async(
×
563
        index,
564
        _system_impl->get_system_id(),
×
565
        [this, callback](MavlinkMissionTransferClient::Result result) {
×
566
            auto converted_result = convert_result(result);
×
567
            _system_impl->call_user_callback([callback, converted_result]() {
×
568
                if (callback) {
569
                    callback(converted_result);
570
                }
571
            });
572
        });
×
573
}
×
574

575
void MissionRawImpl::report_progress_current()
1✔
576
{
577
    std::lock_guard<std::mutex> lock(_mission_progress.mutex);
1✔
578

579
    if (_mission_progress.callbacks.empty()) {
1✔
580
        return;
1✔
581
    }
582

583
    bool should_report = false;
×
584
    {
585
        if (_mission_progress.last_reported.current != _mission_progress.last.current) {
×
586
            _mission_progress.last_reported.current = _mission_progress.last.current;
×
587
            should_report = true;
×
588
        }
589
        if (_mission_progress.last_reported.total != _mission_progress.last.total) {
×
590
            _mission_progress.last_reported.total = _mission_progress.last.total;
×
591
            should_report = true;
×
592
        }
593
    }
594

595
    if (should_report) {
×
596
        _mission_progress.callbacks.queue(_mission_progress.last, [this](const auto& func) {
×
597
            _system_impl->call_user_callback(func);
×
598
        });
×
599
    }
600
}
601

602
MissionRaw::MissionProgressHandle
603
MissionRawImpl::subscribe_mission_progress(const MissionRaw::MissionProgressCallback& callback)
×
604
{
605
    std::lock_guard<std::mutex> lock(_mission_progress.mutex);
×
606
    return _mission_progress.callbacks.subscribe(callback);
×
607
}
608

609
void MissionRawImpl::unsubscribe_mission_progress(MissionRaw::MissionProgressHandle handle)
×
610
{
611
    std::lock_guard<std::mutex> lock(_mission_progress.mutex);
×
612
    _mission_progress.callbacks.unsubscribe(handle);
×
613
}
×
614

615
MissionRaw::MissionProgress MissionRawImpl::mission_progress()
×
616
{
617
    std::lock_guard<std::mutex> lock(_mission_progress.mutex);
×
618
    return _mission_progress.last;
×
619
}
620

621
MissionRaw::MissionChangedHandle
622
MissionRawImpl::subscribe_mission_changed(const MissionRaw::MissionChangedCallback& callback)
×
623
{
624
    std::lock_guard<std::mutex> lock(_mission_changed.mutex);
×
625
    return _mission_changed.callbacks.subscribe(callback);
×
626
}
627

628
void MissionRawImpl::unsubscribe_mission_changed(MissionRaw::MissionChangedHandle handle)
×
629
{
630
    std::lock_guard<std::mutex> lock(_mission_changed.mutex);
×
631
    _mission_changed.callbacks.unsubscribe(handle);
×
632
}
×
633

634
std::pair<MissionRaw::Result, MissionRaw::MissionImportData>
635
MissionRawImpl::import_qgroundcontrol_mission(std::string qgc_plan_path)
1✔
636
{
637
    std::ifstream file(qgc_plan_path);
2✔
638
    if (!file) {
1✔
639
        return std::make_pair<MissionRaw::Result, MissionRaw::MissionImportData>(
640
            MissionRaw::Result::FailedToOpenQgcPlan, {});
×
641
    }
642

643
    std::stringstream buf;
2✔
644
    buf << file.rdbuf();
1✔
645
    file.close();
1✔
646

647
    return MissionImport::parse_json(buf.str(), _system_impl->autopilot());
1✔
648
}
649

650
std::pair<MissionRaw::Result, MissionRaw::MissionImportData>
651
MissionRawImpl::import_qgroundcontrol_mission_from_string(const std::string& qgc_plan)
×
652
{
653
    return MissionImport::parse_json(qgc_plan, _system_impl->autopilot());
×
654
}
655

656
MissionRaw::Result MissionRawImpl::convert_result(MavlinkMissionTransferClient::Result result)
1✔
657
{
658
    switch (result) {
1✔
659
        case MavlinkMissionTransferClient::Result::Success:
1✔
660
            return MissionRaw::Result::Success;
1✔
661
        case MavlinkMissionTransferClient::Result::ConnectionError:
×
662
            return MissionRaw::Result::Error;
×
663
        case MavlinkMissionTransferClient::Result::Denied:
×
664
            return MissionRaw::Result::Denied;
×
665
        case MavlinkMissionTransferClient::Result::TooManyMissionItems:
×
666
            return MissionRaw::Result::TooManyMissionItems;
×
667
        case MavlinkMissionTransferClient::Result::Timeout:
×
668
            return MissionRaw::Result::Timeout;
×
669
        case MavlinkMissionTransferClient::Result::Unsupported:
×
670
            return MissionRaw::Result::Unsupported;
×
671
        case MavlinkMissionTransferClient::Result::UnsupportedFrame:
×
672
            return MissionRaw::Result::Unsupported;
×
673
        case MavlinkMissionTransferClient::Result::NoMissionAvailable:
×
674
            return MissionRaw::Result::NoMissionAvailable;
×
675
        case MavlinkMissionTransferClient::Result::Cancelled:
×
676
            return MissionRaw::Result::TransferCancelled;
×
677
        case MavlinkMissionTransferClient::Result::MissionTypeNotConsistent:
×
678
            return MissionRaw::Result::MissionTypeNotConsistent;
×
679
        case MavlinkMissionTransferClient::Result::InvalidSequence:
×
680
            return MissionRaw::Result::InvalidSequence;
×
681
        case MavlinkMissionTransferClient::Result::CurrentInvalid:
×
682
            return MissionRaw::Result::CurrentInvalid;
×
683
        case MavlinkMissionTransferClient::Result::ProtocolError:
×
684
            return MissionRaw::Result::ProtocolError;
×
685
        case MavlinkMissionTransferClient::Result::InvalidParam:
×
686
            return MissionRaw::Result::InvalidArgument;
×
687
        case MavlinkMissionTransferClient::Result::IntMessagesNotSupported:
×
688
            return MissionRaw::Result::IntMessagesNotSupported;
×
689
        default:
×
690
            return MissionRaw::Result::Unknown;
×
691
    }
692
}
693
} // namespace mavsdk
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc