mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-22 10:33:33 +08:00
dataman: add DatamanClient with sync functions
Rework of dataman
This commit is contained in:
@@ -51,6 +51,7 @@ px4_add_module(
|
||||
geofence.cpp
|
||||
vtol_takeoff.cpp
|
||||
DEPENDS
|
||||
dataman_client
|
||||
geo
|
||||
adsb
|
||||
geofence_breach_avoidance
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "geofence_breach_avoidance.h"
|
||||
#include "fake_geofence.hpp"
|
||||
#include "dataman_mocks.hpp"
|
||||
#include <parameters/param.h>
|
||||
|
||||
using namespace matrix;
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2021 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
/**
|
||||
* @file dataman_mocks.h
|
||||
* Provides a minimal dataman implementation to compile against for testing
|
||||
*
|
||||
* @author Roman Bapst
|
||||
* @author Julian Kent
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <dataman/dataman.h>
|
||||
extern "C" {
|
||||
__EXPORT ssize_t
|
||||
dm_read(
|
||||
dm_item_t item, /* The item type to retrieve */
|
||||
unsigned index, /* The index of the item */
|
||||
void *buffer, /* Pointer to caller data buffer */
|
||||
size_t buflen /* Length in bytes of data to retrieve */
|
||||
) {return 0;};
|
||||
|
||||
/** write to the data manager store */
|
||||
__EXPORT ssize_t
|
||||
dm_write(
|
||||
dm_item_t item, /* The item type to store */
|
||||
unsigned index, /* The index of the item */
|
||||
const void *buffer, /* Pointer to caller data buffer */
|
||||
size_t buflen /* Length in bytes of data to retrieve */
|
||||
) {return 0;};
|
||||
|
||||
/**
|
||||
* Lock all items of a type. Can be used for atomic updates of multiple items (single items are always updated
|
||||
* atomically).
|
||||
* Note that this lock is independent from dm_read & dm_write calls.
|
||||
* @return 0 on success and lock taken, -1 on error (lock not taken, errno set)
|
||||
*/
|
||||
__EXPORT int
|
||||
dm_lock(
|
||||
dm_item_t item /* The item type to lock */
|
||||
) {return 0;};
|
||||
|
||||
/**
|
||||
* Try to lock all items of a type (@see sem_trywait()).
|
||||
* @return 0 if lock is taken, -1 otherwise (on error or if already locked. errno is set accordingly)
|
||||
*/
|
||||
__EXPORT int
|
||||
dm_trylock(
|
||||
dm_item_t item /* The item type to lock */
|
||||
) {return 0;};
|
||||
|
||||
/** Unlock all items of a type */
|
||||
__EXPORT void
|
||||
dm_unlock(
|
||||
dm_item_t item /* The item type to unlock */
|
||||
) {};
|
||||
|
||||
/** Erase all items of this type */
|
||||
__EXPORT int
|
||||
dm_clear(
|
||||
dm_item_t item /* The item type to clear */
|
||||
) {return 0;};
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <dataman/dataman.h>
|
||||
#include <dataman_client/DatamanClient.hpp>
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <lib/geo/geo.h>
|
||||
#include <systemlib/mavlink_log.h>
|
||||
@@ -75,23 +75,26 @@ void Geofence::updateFence()
|
||||
{
|
||||
// Note: be aware that when calling this, it can block for quite some time, the duration of a geofence transfer.
|
||||
// However this is currently not used
|
||||
if (dm_lock(DM_KEY_FENCE_POINTS) != 0) {
|
||||
bool success = _dataman_client.lockSync(DM_KEY_FENCE_POINTS);
|
||||
|
||||
if (!success) {
|
||||
PX4_ERR("lock failed");
|
||||
return;
|
||||
}
|
||||
|
||||
_updateFence();
|
||||
dm_unlock(DM_KEY_FENCE_POINTS);
|
||||
_dataman_client.unlockSync(DM_KEY_FENCE_POINTS);
|
||||
}
|
||||
|
||||
void Geofence::_updateFence()
|
||||
{
|
||||
// initialize fence points count
|
||||
mission_stats_entry_s stats;
|
||||
int ret = dm_read(DM_KEY_FENCE_POINTS, 0, &stats, sizeof(mission_stats_entry_s));
|
||||
bool success = _dataman_client.readSync(DM_KEY_FENCE_POINTS, 0, reinterpret_cast<uint8_t *>(&stats),
|
||||
sizeof(mission_stats_entry_s));
|
||||
int num_fence_items = 0;
|
||||
|
||||
if (ret == sizeof(mission_stats_entry_s)) {
|
||||
if (success) {
|
||||
num_fence_items = stats.num_items;
|
||||
_update_counter = stats.update_counter;
|
||||
}
|
||||
@@ -104,8 +107,10 @@ void Geofence::_updateFence()
|
||||
mission_fence_point_s mission_fence_point;
|
||||
bool is_circle_area = false;
|
||||
|
||||
if (dm_read(DM_KEY_FENCE_POINTS, current_seq, &mission_fence_point, sizeof(mission_fence_point_s)) !=
|
||||
sizeof(mission_fence_point_s)) {
|
||||
success = _dataman_client.readSync(DM_KEY_FENCE_POINTS, current_seq, reinterpret_cast<uint8_t *>(&mission_fence_point),
|
||||
sizeof(mission_fence_point_s));
|
||||
|
||||
if (!success) {
|
||||
PX4_ERR("dm_read failed");
|
||||
break;
|
||||
}
|
||||
@@ -306,22 +311,25 @@ bool Geofence::isBelowMaxAltitude(float altitude)
|
||||
|
||||
bool Geofence::isInsidePolygonOrCircle(double lat, double lon, float altitude)
|
||||
{
|
||||
// the following uses dm_read, so first we try to lock all items. If that fails, it (most likely) means
|
||||
// the following uses readSync, so first we try to lock all items. If that fails, it (most likely) means
|
||||
// the data is currently being updated (via a mavlink geofence transfer), and we do not check for a violation now
|
||||
if (dm_trylock(DM_KEY_FENCE_POINTS) != 0) {
|
||||
bool success = _dataman_client.lockSync(DM_KEY_FENCE_POINTS);
|
||||
|
||||
if (!success) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// we got the lock, now check if the fence data got updated
|
||||
mission_stats_entry_s stats;
|
||||
int ret = dm_read(DM_KEY_FENCE_POINTS, 0, &stats, sizeof(mission_stats_entry_s));
|
||||
success = _dataman_client.readSync(DM_KEY_FENCE_POINTS, 0, reinterpret_cast<uint8_t *>(&stats),
|
||||
sizeof(mission_stats_entry_s));
|
||||
|
||||
if (ret == sizeof(mission_stats_entry_s) && _update_counter != stats.update_counter) {
|
||||
if (success && _update_counter != stats.update_counter) {
|
||||
_updateFence();
|
||||
}
|
||||
|
||||
if (isEmpty()) {
|
||||
dm_unlock(DM_KEY_FENCE_POINTS);
|
||||
_dataman_client.unlockSync(DM_KEY_FENCE_POINTS);
|
||||
/* Empty fence -> accept all points */
|
||||
return true;
|
||||
}
|
||||
@@ -329,7 +337,7 @@ bool Geofence::isInsidePolygonOrCircle(double lat, double lon, float altitude)
|
||||
/* Vertical check */
|
||||
if (_altitude_max > _altitude_min) { // only enable vertical check if configured properly
|
||||
if (altitude > _altitude_max || altitude < _altitude_min) {
|
||||
dm_unlock(DM_KEY_FENCE_POINTS);
|
||||
_dataman_client.unlockSync(DM_KEY_FENCE_POINTS);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -375,7 +383,7 @@ bool Geofence::isInsidePolygonOrCircle(double lat, double lon, float altitude)
|
||||
}
|
||||
}
|
||||
|
||||
dm_unlock(DM_KEY_FENCE_POINTS);
|
||||
_dataman_client.unlockSync(DM_KEY_FENCE_POINTS);
|
||||
|
||||
return (!had_inclusion_areas || inside_inclusion) && outside_exclusion;
|
||||
}
|
||||
@@ -394,13 +402,18 @@ bool Geofence::insidePolygon(const PolygonInfo &polygon, double lat, double lon,
|
||||
bool c = false;
|
||||
|
||||
for (unsigned i = 0, j = polygon.vertex_count - 1; i < polygon.vertex_count; j = i++) {
|
||||
if (dm_read(DM_KEY_FENCE_POINTS, polygon.dataman_index + i, &temp_vertex_i,
|
||||
sizeof(mission_fence_point_s)) != sizeof(mission_fence_point_s)) {
|
||||
|
||||
bool success = _dataman_client.readSync(DM_KEY_FENCE_POINTS, polygon.dataman_index + i,
|
||||
reinterpret_cast<uint8_t *>(&temp_vertex_i), sizeof(mission_fence_point_s));
|
||||
|
||||
if (!success) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (dm_read(DM_KEY_FENCE_POINTS, polygon.dataman_index + j, &temp_vertex_j,
|
||||
sizeof(mission_fence_point_s)) != sizeof(mission_fence_point_s)) {
|
||||
success = _dataman_client.readSync(DM_KEY_FENCE_POINTS, polygon.dataman_index + j,
|
||||
reinterpret_cast<uint8_t *>(&temp_vertex_j), sizeof(mission_fence_point_s));
|
||||
|
||||
if (!success) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -426,9 +439,10 @@ bool Geofence::insideCircle(const PolygonInfo &polygon, double lat, double lon,
|
||||
{
|
||||
|
||||
mission_fence_point_s circle_point{};
|
||||
bool success = _dataman_client.readSync(DM_KEY_FENCE_POINTS, polygon.dataman_index,
|
||||
reinterpret_cast<uint8_t *>(&circle_point), sizeof(mission_fence_point_s));
|
||||
|
||||
if (dm_read(DM_KEY_FENCE_POINTS, polygon.dataman_index, &circle_point,
|
||||
sizeof(mission_fence_point_s)) != sizeof(mission_fence_point_s)) {
|
||||
if (!success) {
|
||||
PX4_ERR("dm_read failed");
|
||||
return false;
|
||||
}
|
||||
@@ -531,7 +545,10 @@ Geofence::loadFromFile(const char *filename)
|
||||
}
|
||||
}
|
||||
|
||||
if (dm_write(DM_KEY_FENCE_POINTS, pointCounter + 1, &vertex, sizeof(vertex)) != sizeof(vertex)) {
|
||||
bool success = _dataman_client.writeSync(DM_KEY_FENCE_POINTS, pointCounter + 1, reinterpret_cast<uint8_t *>(&vertex),
|
||||
sizeof(vertex));
|
||||
|
||||
if (!success) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -555,22 +572,31 @@ Geofence::loadFromFile(const char *filename)
|
||||
if (gotVertical && pointCounter > 2) {
|
||||
mavlink_log_info(_navigator->get_mavlink_log_pub(), "Geofence imported\t");
|
||||
events::send(events::ID("navigator_geofence_imported"), events::Log::Info, "Geofence imported");
|
||||
ret_val = PX4_OK;
|
||||
ret_val = PX4_ERROR;
|
||||
|
||||
/* do a second pass, now that we know the number of vertices */
|
||||
for (int seq = 1; seq <= pointCounter; ++seq) {
|
||||
mission_fence_point_s mission_fence_point;
|
||||
|
||||
if (dm_read(DM_KEY_FENCE_POINTS, seq, &mission_fence_point, sizeof(mission_fence_point_s)) ==
|
||||
sizeof(mission_fence_point_s)) {
|
||||
bool success = _dataman_client.readSync(DM_KEY_FENCE_POINTS, seq, reinterpret_cast<uint8_t *>(&mission_fence_point),
|
||||
sizeof(mission_fence_point_s));
|
||||
|
||||
if (success) {
|
||||
mission_fence_point.vertex_count = pointCounter;
|
||||
dm_write(DM_KEY_FENCE_POINTS, seq, &mission_fence_point, sizeof(mission_fence_point_s));
|
||||
_dataman_client.writeSync(DM_KEY_FENCE_POINTS, seq, reinterpret_cast<uint8_t *>(&mission_fence_point),
|
||||
sizeof(mission_fence_point_s));
|
||||
}
|
||||
}
|
||||
|
||||
mission_stats_entry_s stats;
|
||||
stats.num_items = pointCounter;
|
||||
ret_val = dm_write(DM_KEY_FENCE_POINTS, 0, &stats, sizeof(mission_stats_entry_s));
|
||||
|
||||
bool success = _dataman_client.writeSync(DM_KEY_FENCE_POINTS, 0, reinterpret_cast<uint8_t *>(&stats),
|
||||
sizeof(mission_stats_entry_s));
|
||||
|
||||
if (success) {
|
||||
ret_val = PX4_OK;
|
||||
}
|
||||
|
||||
} else {
|
||||
mavlink_log_critical(_navigator->get_mavlink_log_pub(), "Geofence: import error\t");
|
||||
@@ -586,7 +612,7 @@ error:
|
||||
|
||||
int Geofence::clearDm()
|
||||
{
|
||||
dm_clear(DM_KEY_FENCE_POINTS);
|
||||
_dataman_client.clearSync(DM_KEY_FENCE_POINTS);
|
||||
updateFence();
|
||||
return PX4_OK;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#include <dataman_client/DatamanClient.hpp>
|
||||
#include <lib/mathlib/mathlib.h>
|
||||
#include <px4_platform_common/module_params.h>
|
||||
#include <drivers/drv_hrt.h>
|
||||
@@ -166,6 +167,8 @@ private:
|
||||
Navigator *_navigator{nullptr};
|
||||
PolygonInfo *_polygons{nullptr};
|
||||
|
||||
DatamanClient _dataman_client{};
|
||||
|
||||
hrt_abstime _last_horizontal_range_warning{0};
|
||||
hrt_abstime _last_vertical_range_warning{0};
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <dataman/dataman.h>
|
||||
#include <dataman_client/DatamanClient.hpp>
|
||||
#include <systemlib/mavlink_log.h>
|
||||
#include <systemlib/err.h>
|
||||
#include <lib/geo/geo.h>
|
||||
@@ -75,7 +75,7 @@ void Mission::mission_init()
|
||||
// init mission state, do it here to allow navigator to use stored mission even if mavlink failed to start
|
||||
mission_s mission{};
|
||||
|
||||
if (dm_read(DM_KEY_MISSION_STATE, 0, &mission, sizeof(mission_s)) == sizeof(mission_s)) {
|
||||
if (_dataman_client.readSync(DM_KEY_MISSION_STATE, 0, reinterpret_cast<uint8_t *>(&mission), sizeof(mission_s))) {
|
||||
if ((mission.timestamp != 0)
|
||||
&& (mission.dataman_id == DM_KEY_WAYPOINTS_OFFBOARD_0 || mission.dataman_id == DM_KEY_WAYPOINTS_OFFBOARD_1)) {
|
||||
if (mission.count > 0) {
|
||||
@@ -88,7 +88,7 @@ void Mission::mission_init()
|
||||
// initialize mission state in dataman
|
||||
mission.dataman_id = DM_KEY_WAYPOINTS_OFFBOARD_0;
|
||||
mission.timestamp = hrt_absolute_time();
|
||||
dm_write(DM_KEY_MISSION_STATE, 0, &mission, sizeof(mission_s));
|
||||
_dataman_client.writeSync(DM_KEY_MISSION_STATE, 0, reinterpret_cast<uint8_t *>(&mission), sizeof(mission_s));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,14 +124,11 @@ Mission::on_inactive()
|
||||
/* load missions from storage */
|
||||
mission_s mission_state = {};
|
||||
|
||||
dm_lock(DM_KEY_MISSION_STATE);
|
||||
|
||||
/* read current state */
|
||||
int read_res = dm_read(DM_KEY_MISSION_STATE, 0, &mission_state, sizeof(mission_s));
|
||||
bool success = _dataman_client.readSync(DM_KEY_MISSION_STATE, 0, reinterpret_cast<uint8_t *>(&mission_state),
|
||||
sizeof(mission_s));
|
||||
|
||||
dm_unlock(DM_KEY_MISSION_STATE);
|
||||
|
||||
if (read_res == sizeof(mission_s)) {
|
||||
if (success) {
|
||||
_mission.dataman_id = mission_state.dataman_id;
|
||||
_mission.count = mission_state.count;
|
||||
_current_mission_index = mission_state.current_seq;
|
||||
@@ -464,10 +461,12 @@ Mission::find_mission_land_start()
|
||||
bool found_land_start_marker = false;
|
||||
|
||||
for (size_t i = 1; i < _mission.count; i++) {
|
||||
const ssize_t len = sizeof(missionitem);
|
||||
missionitem_prev = missionitem; // store the last mission item before reading a new one
|
||||
|
||||
if (dm_read(dm_current, i, &missionitem, len) != len) {
|
||||
bool success = _dataman_client.readSync(dm_current, i, reinterpret_cast<uint8_t *>(&missionitem),
|
||||
sizeof(mission_item_s));
|
||||
|
||||
if (!success) {
|
||||
/* not supposed to happen unless the datamanager can't access the SD card, etc. */
|
||||
PX4_ERR("dataman read failure");
|
||||
break;
|
||||
@@ -668,9 +667,11 @@ Mission::advance_mission()
|
||||
|
||||
for (int32_t i = _current_mission_index - 1; i >= 0; i--) {
|
||||
struct mission_item_s missionitem = {};
|
||||
const ssize_t len = sizeof(missionitem);
|
||||
|
||||
if (dm_read(dm_current, i, &missionitem, len) != len) {
|
||||
bool success = _dataman_client.readSync(dm_current, i, reinterpret_cast<uint8_t *>(&missionitem),
|
||||
sizeof(mission_item_s));
|
||||
|
||||
if (!success) {
|
||||
/* not supposed to happen unless the datamanager can't access the SD card, etc. */
|
||||
PX4_ERR("dataman read failure");
|
||||
break;
|
||||
@@ -1641,13 +1642,14 @@ Mission::read_mission_item(int offset, struct mission_item_s *mission_item)
|
||||
return false;
|
||||
}
|
||||
|
||||
const ssize_t len = sizeof(struct mission_item_s);
|
||||
|
||||
/* read mission item to temp storage first to not overwrite current mission item if data damaged */
|
||||
struct mission_item_s mission_item_tmp;
|
||||
|
||||
/* read mission item from datamanager */
|
||||
if (dm_read(dm_item, *mission_index_ptr, &mission_item_tmp, len) != len) {
|
||||
bool success = _dataman_client.readSync(dm_item, *mission_index_ptr, reinterpret_cast<uint8_t *>(&mission_item_tmp),
|
||||
sizeof(mission_item_s));
|
||||
|
||||
if (!success) {
|
||||
/* not supposed to happen unless the datamanager can't access the SD card, etc. */
|
||||
mavlink_log_critical(_navigator->get_mavlink_log_pub(), "Waypoint could not be read.\t");
|
||||
events::send<uint16_t>(events::ID("mission_failed_to_read_wp"), events::Log::Error,
|
||||
@@ -1668,7 +1670,10 @@ Mission::read_mission_item(int offset, struct mission_item_s *mission_item)
|
||||
(mission_item_tmp.do_jump_current_count)++;
|
||||
|
||||
/* save repeat count */
|
||||
if (dm_write(dm_item, *mission_index_ptr, &mission_item_tmp, len) != len) {
|
||||
success = _dataman_client.writeSync(dm_item, *mission_index_ptr, reinterpret_cast<uint8_t *>(&mission_item_tmp),
|
||||
sizeof(struct mission_item_s));
|
||||
|
||||
if (!success) {
|
||||
/* not supposed to happen unless the datamanager can't access the dataman */
|
||||
mavlink_log_critical(_navigator->get_mavlink_log_pub(), "DO JUMP waypoint could not be written.\t");
|
||||
events::send(events::ID("mission_failed_to_write_do_jump"), events::Log::Error,
|
||||
@@ -1718,16 +1723,17 @@ Mission::save_mission_state()
|
||||
mission_s mission_state = {};
|
||||
|
||||
/* lock MISSION_STATE item */
|
||||
int dm_lock_ret = dm_lock(DM_KEY_MISSION_STATE);
|
||||
bool success_lock = _dataman_client.lockSync(DM_KEY_MISSION_STATE);
|
||||
|
||||
if (dm_lock_ret != 0) {
|
||||
if (!success_lock) {
|
||||
PX4_ERR("DM_KEY_MISSION_STATE lock failed");
|
||||
}
|
||||
|
||||
/* read current state */
|
||||
int read_res = dm_read(DM_KEY_MISSION_STATE, 0, &mission_state, sizeof(mission_s));
|
||||
bool success = _dataman_client.readSync(DM_KEY_MISSION_STATE, 0, reinterpret_cast<uint8_t *>(&mission_state),
|
||||
sizeof(mission_s));
|
||||
|
||||
if (read_res == sizeof(mission_s)) {
|
||||
if (success) {
|
||||
/* data read successfully, check dataman ID and items count */
|
||||
if (mission_state.dataman_id == _mission.dataman_id && mission_state.count == _mission.count) {
|
||||
/* navigator may modify only sequence, write modified state only if it changed */
|
||||
@@ -1735,7 +1741,10 @@ Mission::save_mission_state()
|
||||
mission_state.current_seq = _current_mission_index;
|
||||
mission_state.timestamp = hrt_absolute_time();
|
||||
|
||||
if (dm_write(DM_KEY_MISSION_STATE, 0, &mission_state, sizeof(mission_s)) != sizeof(mission_s)) {
|
||||
success = _dataman_client.writeSync(DM_KEY_MISSION_STATE, 0, reinterpret_cast<uint8_t *>(&mission_state),
|
||||
sizeof(mission_s));
|
||||
|
||||
if (!success) {
|
||||
|
||||
PX4_ERR("Can't save mission state");
|
||||
}
|
||||
@@ -1756,15 +1765,18 @@ Mission::save_mission_state()
|
||||
events::send(events::ID("mission_invalid_mission_state"), events::Log::Error, "Invalid mission state");
|
||||
|
||||
/* write modified state only if changed */
|
||||
if (dm_write(DM_KEY_MISSION_STATE, 0, &mission_state, sizeof(mission_s)) != sizeof(mission_s)) {
|
||||
success = _dataman_client.writeSync(DM_KEY_MISSION_STATE, 0, reinterpret_cast<uint8_t *>(&mission_state),
|
||||
sizeof(mission_s));
|
||||
|
||||
if (!success) {
|
||||
|
||||
PX4_ERR("Can't save mission state");
|
||||
}
|
||||
}
|
||||
|
||||
/* unlock MISSION_STATE item */
|
||||
if (dm_lock_ret == 0) {
|
||||
dm_unlock(DM_KEY_MISSION_STATE);
|
||||
if (success_lock) {
|
||||
_dataman_client.unlockSync(DM_KEY_MISSION_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1821,9 +1833,9 @@ Mission::check_mission_valid(bool force)
|
||||
void
|
||||
Mission::reset_mission(struct mission_s &mission)
|
||||
{
|
||||
dm_lock(DM_KEY_MISSION_STATE);
|
||||
_dataman_client.lockSync(DM_KEY_MISSION_STATE);
|
||||
|
||||
if (dm_read(DM_KEY_MISSION_STATE, 0, &mission, sizeof(mission_s)) == sizeof(mission_s)) {
|
||||
if (_dataman_client.readSync(DM_KEY_MISSION_STATE, 0, reinterpret_cast<uint8_t *>(&mission), sizeof(mission_s))) {
|
||||
if (mission.dataman_id == DM_KEY_WAYPOINTS_OFFBOARD_0 || mission.dataman_id == DM_KEY_WAYPOINTS_OFFBOARD_1) {
|
||||
/* set current item to 0 */
|
||||
mission.current_seq = 0;
|
||||
@@ -1836,7 +1848,9 @@ Mission::reset_mission(struct mission_s &mission)
|
||||
struct mission_item_s item;
|
||||
const ssize_t len = sizeof(struct mission_item_s);
|
||||
|
||||
if (dm_read(dm_current, index, &item, len) != len) {
|
||||
bool success = _dataman_client.readSync(dm_current, index, reinterpret_cast<uint8_t *>(&item), sizeof(mission_item_s));
|
||||
|
||||
if (!success) {
|
||||
PX4_WARN("could not read mission item during reset");
|
||||
break;
|
||||
}
|
||||
@@ -1844,7 +1858,9 @@ Mission::reset_mission(struct mission_s &mission)
|
||||
if (item.nav_cmd == NAV_CMD_DO_JUMP) {
|
||||
item.do_jump_current_count = 0;
|
||||
|
||||
if (dm_write(dm_current, index, &item, len) != len) {
|
||||
success = _dataman_client.writeSync(dm_current, index, reinterpret_cast<uint8_t *>(&item), len);
|
||||
|
||||
if (!success) {
|
||||
PX4_WARN("could not save mission item during reset");
|
||||
break;
|
||||
}
|
||||
@@ -1863,10 +1879,10 @@ Mission::reset_mission(struct mission_s &mission)
|
||||
mission.current_seq = 0;
|
||||
}
|
||||
|
||||
dm_write(DM_KEY_MISSION_STATE, 0, &mission, sizeof(mission_s));
|
||||
_dataman_client.writeSync(DM_KEY_MISSION_STATE, 0, reinterpret_cast<uint8_t *>(&mission), sizeof(mission_s));
|
||||
}
|
||||
|
||||
dm_unlock(DM_KEY_MISSION_STATE);
|
||||
_dataman_client.unlockSync(DM_KEY_MISSION_STATE);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1883,7 +1899,7 @@ Mission::need_to_reset_mission()
|
||||
}
|
||||
|
||||
int32_t
|
||||
Mission::index_closest_mission_item() const
|
||||
Mission::index_closest_mission_item()
|
||||
{
|
||||
int32_t min_dist_index(0);
|
||||
float min_dist(FLT_MAX), dist_xy(FLT_MAX), dist_z(FLT_MAX);
|
||||
@@ -1892,9 +1908,11 @@ Mission::index_closest_mission_item() const
|
||||
|
||||
for (size_t i = 0; i < _mission.count; i++) {
|
||||
struct mission_item_s missionitem = {};
|
||||
const ssize_t len = sizeof(missionitem);
|
||||
|
||||
if (dm_read(dm_current, i, &missionitem, len) != len) {
|
||||
bool success = _dataman_client.readSync(dm_current, i, reinterpret_cast<uint8_t *>(&missionitem),
|
||||
sizeof(mission_item_s));
|
||||
|
||||
if (!success) {
|
||||
/* not supposed to happen unless the datamanager can't access the SD card, etc. */
|
||||
PX4_ERR("dataman read failure");
|
||||
break;
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#include <dataman/dataman.h>
|
||||
#include <dataman_client/DatamanClient.hpp>
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <px4_platform_common/module_params.h>
|
||||
#include <uORB/Subscription.hpp>
|
||||
@@ -234,7 +234,7 @@ private:
|
||||
/**
|
||||
* Return the index of the closest mission item to the current global position.
|
||||
*/
|
||||
int32_t index_closest_mission_item() const;
|
||||
int32_t index_closest_mission_item();
|
||||
|
||||
bool position_setpoint_equal(const position_setpoint_s *p1, const position_setpoint_s *p2) const;
|
||||
|
||||
@@ -323,6 +323,7 @@ private:
|
||||
|
||||
uORB::Subscription _mission_sub{ORB_ID(mission)}; /**< mission subscription */
|
||||
mission_s _mission {};
|
||||
DatamanClient _dataman_client{};
|
||||
|
||||
int32_t _current_mission_index{-1};
|
||||
|
||||
|
||||
@@ -78,9 +78,11 @@ MissionFeasibilityChecker::checkMissionFeasible(const mission_s &mission)
|
||||
|
||||
for (size_t i = 0; i < mission.count; i++) {
|
||||
struct mission_item_s missionitem = {};
|
||||
const ssize_t len = sizeof(struct mission_item_s);
|
||||
|
||||
if (dm_read((dm_item_t)mission.dataman_id, i, &missionitem, len) != len) {
|
||||
bool success = _dataman_client.readSync((dm_item_t)mission.dataman_id, i, reinterpret_cast<uint8_t *>(&missionitem),
|
||||
sizeof(mission_item_s));
|
||||
|
||||
if (!success) {
|
||||
_navigator->get_mission_result()->warning = true;
|
||||
/* not supposed to happen unless the datamanager can't access the SD card, etc. */
|
||||
return false;
|
||||
@@ -116,9 +118,11 @@ MissionFeasibilityChecker::checkGeofence(const mission_s &mission, float home_al
|
||||
if (_navigator->get_geofence().valid()) {
|
||||
for (size_t i = 0; i < mission.count; i++) {
|
||||
struct mission_item_s missionitem = {};
|
||||
const ssize_t len = sizeof(missionitem);
|
||||
|
||||
if (dm_read((dm_item_t)mission.dataman_id, i, &missionitem, len) != len) {
|
||||
bool success = _dataman_client.readSync((dm_item_t)mission.dataman_id, i, reinterpret_cast<uint8_t *>(&missionitem),
|
||||
sizeof(mission_item_s));
|
||||
|
||||
if (!success) {
|
||||
/* not supposed to happen unless the datamanager can't access the SD card, etc. */
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <dataman/dataman.h>
|
||||
#include <dataman_client/DatamanClient.hpp>
|
||||
#include <uORB/topics/mission.h>
|
||||
#include <px4_platform_common/module_params.h>
|
||||
#include "MissionFeasibility/FeasibilityChecker.hpp"
|
||||
@@ -75,4 +75,6 @@ public:
|
||||
* Returns true if mission is feasible and false otherwise
|
||||
*/
|
||||
bool checkMissionFeasible(const mission_s &mission);
|
||||
|
||||
DatamanClient _dataman_client{};
|
||||
};
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
#include <float.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <dataman/dataman.h>
|
||||
#include <dataman_client/DatamanClient.hpp>
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <lib/geo/geo.h>
|
||||
#include <lib/adsb/AdsbConflict.h>
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
#include "rtl.h"
|
||||
#include "navigator.h"
|
||||
#include <dataman/dataman.h>
|
||||
#include <dataman_client/DatamanClient.hpp>
|
||||
#include <px4_platform_common/events.h>
|
||||
|
||||
#include <lib/geo/geo.h>
|
||||
@@ -181,10 +181,11 @@ void RTL::find_RTL_destination()
|
||||
// compare to safe landing positions
|
||||
mission_safe_point_s closest_safe_point {};
|
||||
mission_stats_entry_s stats;
|
||||
int ret = dm_read(DM_KEY_SAFE_POINTS, 0, &stats, sizeof(mission_stats_entry_s));
|
||||
bool success = _dataman_client.readSync(DM_KEY_SAFE_POINTS, 0, reinterpret_cast<uint8_t *>(&stats),
|
||||
sizeof(mission_stats_entry_s));
|
||||
int num_safe_points = 0;
|
||||
|
||||
if (ret == sizeof(mission_stats_entry_s)) {
|
||||
if (success) {
|
||||
num_safe_points = stats.num_items;
|
||||
}
|
||||
|
||||
@@ -194,8 +195,10 @@ void RTL::find_RTL_destination()
|
||||
for (int current_seq = 1; current_seq <= num_safe_points; ++current_seq) {
|
||||
mission_safe_point_s mission_safe_point;
|
||||
|
||||
if (dm_read(DM_KEY_SAFE_POINTS, current_seq, &mission_safe_point, sizeof(mission_safe_point_s)) !=
|
||||
sizeof(mission_safe_point_s)) {
|
||||
success = _dataman_client.readSync(DM_KEY_SAFE_POINTS, current_seq, reinterpret_cast<uint8_t *>(&mission_safe_point),
|
||||
sizeof(mission_safe_point_s));
|
||||
|
||||
if (!success) {
|
||||
PX4_ERR("dm_read failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include <uORB/topics/wind.h>
|
||||
#include <matrix/math.hpp>
|
||||
#include <lib/geo/geo.h>
|
||||
#include <dataman_client/DatamanClient.hpp>
|
||||
|
||||
class Navigator;
|
||||
|
||||
@@ -156,6 +157,8 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
DatamanClient _dataman_client{};
|
||||
|
||||
RTLPosition _destination{}; ///< the RTL position to fly to (typically the home position or a safe point)
|
||||
|
||||
hrt_abstime _destination_check_time{0};
|
||||
|
||||
Reference in New Issue
Block a user