Compare commits

..

11 Commits

Author SHA1 Message Date
JaeyoungLim 21b4052d82 Log camera topics 2023-03-30 19:05:50 +02:00
Jaeyoung Lim 8296d02b1e Eliminate intermediate variable 2023-03-28 18:48:26 +02:00
Jaeyoung Lim e3db31f5ab Add fw state for path following 2023-03-28 17:13:07 +02:00
Ramon Roche 319f3db5e1 tools: ip converter remove verbose output 2023-03-27 10:28:43 -07:00
Beniamino Pozzan 51dd6b783c microdds_client: Mark parameter as used only if truly used
Signed-off-by: Beniamino Pozzan <beniamino.pozzan@phd.unipd.it>
2023-03-27 10:28:43 -07:00
Beniamino Pozzan c7f67a3328 microdds_client: remove multi-instances supports, add agent IP as PX4 parameter
- multi-instances support is removed from the parameter definitions.

- XRCE_DDS_AG_IP allows to define the agent IP when udp transport is used.
The parameter is used by default if the module is started without the -h argument.

- XRCE_DDS_PRT allows to define the agent listning udp port when the
udp transport is uded. The parameter is used by default if the module is started
without the -p argument.

- Tools/convert_ip.py assists in converting ips in decimal dot notation into int32
notation.

Signed-off-by: Beniamino Pozzan <beniamino.pozzan@phd.unipd.it>
2023-03-27 10:28:43 -07:00
Daniel Mesham 6fddbea3e4 microdds_client: fix check for length of participant XML (#21374) 2023-03-27 10:03:09 -07:00
Silvan Fuhrer ba17a137e1 Navigator: MissionFeasibiltyCheck first WP: check only to current vehicle position
Signed-off-by: Silvan Fuhrer <silvan@auterion.com>
2023-03-27 17:43:33 +02:00
Silvan Fuhrer 465ddddbfd Navigator: take min of vehicle position or Home distance for first WP check
To prevent mission rejections when vehicle is currently far away from Mission start,
but planned home is close to it.

Signed-off-by: Silvan Fuhrer <silvan@auterion.com>
2023-03-27 17:43:33 +02:00
Silvan Fuhrer d8ed35c422 Navigator: take vehicle position for first-WP-distance-check
And only use Home position if current vehicle position is unknown.

Signed-off-by: Silvan Fuhrer <silvan@auterion.com>
2023-03-27 17:43:33 +02:00
Silvan Fuhrer 4d2a31afe3 Navigator: remove max distance between WP mission feasibility check (MIS_DIST_WPS)
Signed-off-by: Silvan Fuhrer <silvan@auterion.com>
2023-03-27 17:43:33 +02:00
37 changed files with 400 additions and 297 deletions
+1 -1
View File
@@ -256,7 +256,7 @@ endif()
set(package-contact "px4users@googlegroups.com")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
@@ -25,7 +25,6 @@ param set-default FW_W_EN 1
param set-default MIS_TAKEOFF_ALT 20
param set-default MIS_DIST_1WP 2500
param set-default MIS_DIST_WPS 10000
param set-default NAV_ACC_RAD 15
param set-default NAV_DLL_ACT 2
@@ -25,7 +25,6 @@ param set-default FW_W_EN 1
param set-default MIS_TAKEOFF_ALT 20
param set-default MIS_DIST_1WP 2500
param set-default MIS_DIST_WPS 10000
param set-default NAV_ACC_RAD 15
param set-default NAV_DLL_ACT 2
@@ -25,7 +25,6 @@ param set-default FW_W_EN 1
param set-default MIS_TAKEOFF_ALT 20
param set-default MIS_DIST_1WP 2500
param set-default MIS_DIST_WPS 10000
param set-default NAV_ACC_RAD 15
param set-default NAV_DLL_ACT 2
@@ -27,7 +27,6 @@ param set-default FW_W_EN 1
param set-default MIS_LTRMIN_ALT 30
param set-default MIS_TAKEOFF_ALT 20
param set-default MIS_DIST_1WP 2500
param set-default MIS_DIST_WPS 10000
param set-default NAV_ACC_RAD 15
param set-default NAV_DLL_ACT 2
+1 -1
View File
@@ -277,7 +277,7 @@ then
# Override namespace if environment variable is defined
microdds_ns="-n $PX4_MICRODDS_NS"
fi
microdds_client start -t udp -p 8888 $microdds_ns
microdds_client start -t udp -h 127.0.0.1 -p 8888 $microdds_ns
if param greater -s MNT_MODE_IN -1
then
@@ -79,7 +79,6 @@ param set-default MC_YAWRATE_MAX 20
param set-default MC_AIRMODE 1
param set-default MIS_DIST_1WP 100
param set-default MIS_DIST_WPS 100000
param set-default MIS_TAKEOFF_ALT 15
param set-default MPC_XY_P 0.8
@@ -46,7 +46,6 @@ param set-default RTL_LAND_DELAY -1
#
param set-default NAV_ACC_RAD 10
param set-default MIS_DIST_WPS 5000
param set-default MIS_TAKEOFF_ALT 25
param set-default MIS_TKO_LAND_REQ 2
@@ -23,7 +23,6 @@ param set-default EKF2_FUSE_BETA 1
param set-default HTE_VXY_THR 2.0
param set-default MIS_DIST_WPS 5000
param set-default MIS_TKO_LAND_REQ 2
param set-default MPC_ACC_HOR_MAX 2
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
"""
Converts IP address given in decimal dot notation to int32 to be used in XRCE_DDS_0_CFG parameter
and vice-versa
@author: Beniamino Pozzan (beniamino.pozzan@phd.unipd.it)
"""
import argparse
parser = argparse.ArgumentParser(
prog = 'convert_ip',
description = 'converts IP to int32 and viceversa'
)
parser.add_argument('input',
type=str,
help='IP address to convert')
parser.add_argument('-r','--reverse',
action='store_true',
help='converts from int32 to dot decimal')
args = parser.parse_args()
if( args.reverse == False ):
try:
ip_parts = [int(x) for x in args.input.split('.')]
except:
raise ValueError("Not a valid IP")
if( len(ip_parts)!=4 ):
raise ValueError("Not a valid IP")
if( not all(x>=0 and x<255 for x in ip_parts) ):
raise ValueError("Not a valid IP")
ip = (ip_parts[0]<<24) + (ip_parts[1]<<16) + (ip_parts[2]<<8) + ip_parts[3]
if(ip & 0x80000000):
ip = -0x100000000 + ip
print(ip)
else:
try:
ip = int(args.input)
except:
raise ValueError("Not a valid IP")
if(ip < 0):
ip = ip + 0x100000000
print('{}.{}.{}.{}'.format(ip>>24, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff))
-67
View File
@@ -245,71 +245,4 @@ private:
T _data{};
};
template<auto member>
class SubscriptionSelection;
template <class T, class R, R T::*member>
class SubscriptionSelection<member>: public Subscription
{
public:
/**
* Constructor
*
* @param id The uORB metadata ORB_ID enum for the topic.
* @param instance The instance for multi sub.
*/
SubscriptionSelection(ORB_ID id, uint8_t instance = 0) :
Subscription(id, instance)
{
_copySelection();
}
/**
* Constructor
*
* @param meta The uORB metadata (usually from the ORB_ID() macro) for the topic.
* @param instance The instance for multi sub.
*/
SubscriptionSelection(const orb_metadata *meta, uint8_t instance = 0) :
Subscription(meta, instance)
{
_copySelection();
}
~SubscriptionSelection() = default;
// no copy, assignment, move, move assignment
SubscriptionSelection(const SubscriptionSelection &) = delete;
SubscriptionSelection &operator=(const SubscriptionSelection &) = delete;
SubscriptionSelection(SubscriptionSelection &&) = delete;
SubscriptionSelection &operator=(SubscriptionSelection &&) = delete;
// update the embedded struct.
bool update()
{
bool updated = Subscription::updated();
if (updated) {
_copySelection();
}
return updated;
}
const R &get() const { return _data; }
private:
void _copySelection()
{
T full_data;
if (copy(&full_data)) {
_data = full_data.*member;
}
}
R _data{};
};
} // namespace uORB
+10 -5
View File
@@ -325,7 +325,13 @@ void RCInput::Run()
updateParams();
}
_vehicle_status_arming_state_sub.update();
if (_vehicle_status_sub.updated()) {
vehicle_status_s vehicle_status;
if (_vehicle_status_sub.copy(&vehicle_status)) {
_armed = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED);
}
}
const hrt_abstime cycle_timestamp = hrt_absolute_time();
@@ -340,7 +346,7 @@ void RCInput::Run()
uint8_t cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_UNSUPPORTED;
#if defined(SPEKTRUM_POWER)
if (!_rc_scan_locked && !(_vehicle_status_arming_state_sub.get() == vehicle_status_s::ARMING_STATE_ARMED)) {
if (!_rc_scan_locked && !_armed) {
if ((int)vcmd.param1 == 0) {
// DSM binding command
int dsm_bind_mode = (int)vcmd.param2;
@@ -752,8 +758,7 @@ void RCInput::Run()
_to_input_rc.publish(_rc_in);
} else if (!rc_updated && !(_vehicle_status_arming_state_sub.get() == vehicle_status_s::ARMING_STATE_ARMED)
&& (hrt_elapsed_time(&_rc_in.timestamp_last_signal) > 1_s)) {
} else if (!rc_updated && !_armed && (hrt_elapsed_time(&_rc_in.timestamp_last_signal) > 1_s)) {
_rc_scan_locked = false;
}
@@ -762,7 +767,7 @@ void RCInput::Run()
}
// set RC_INPUT_PROTO if RC successfully locked for > 3 seconds
if (!(_vehicle_status_arming_state_sub.get() == vehicle_status_s::ARMING_STATE_ARMED) && rc_updated && _rc_scan_locked
if (!_armed && rc_updated && _rc_scan_locked
&& ((_rc_scan_begin != 0) && hrt_elapsed_time(&_rc_scan_begin) > 3_s)
&& (_param_rc_input_proto.get() < 0)
) {
+4 -1
View File
@@ -138,13 +138,16 @@ private:
uORB::Subscription _adc_report_sub{ORB_ID(adc_report)};
uORB::Subscription _vehicle_cmd_sub{ORB_ID(vehicle_command)};
uORB::SubscriptionSelection<&vehicle_status_s::arming_state> _vehicle_status_arming_state_sub{ORB_ID(vehicle_status)};
uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)};
input_rc_s _rc_in{};
float _analog_rc_rssi_volt{-1.0f};
bool _analog_rc_rssi_stable{false};
bool _armed{false};
uORB::PublicationMulti<input_rc_s> _to_input_rc{ORB_ID(input_rc)};
int _rcs_fd{-1};
+13 -12
View File
@@ -70,27 +70,28 @@ CameraFeedback::Run()
camera_trigger_s trig{};
while (_trigger_sub.update(&trig)) {
vehicle_attitude_s att{};
while (_att_sub.update(&att)) {
// update geotagging subscriptions
vehicle_global_position_s gpos{};
_gpos_sub.copy(&gpos);
vehicle_attitude_s att{};
_att_sub.copy(&att);
_trigger_sub.copy(&trig);
if (trig.timestamp == 0 ||
gpos.timestamp == 0 ||
att.timestamp == 0) {
// if (trig.timestamp == 0 ||
// gpos.timestamp == 0 ||
// att.timestamp == 0) {
// reject until we have valid data
continue;
}
// // reject until we have valid data
// continue;
// }
if ((_cam_cap_fback >= 1) && !trig.feedback) {
// Ignore triggers that are not feedback when camera capture feedback is enabled
continue;
}
// if ((_cam_cap_fback >= 1) && !trig.feedback) {
// // Ignore triggers that are not feedback when camera capture feedback is enabled
// continue;
// }
camera_capture_s capture{};
@@ -106,8 +106,14 @@ void FwAutotuneAttitudeControl::Run()
return;
}
_vehicle_status_armed_state_sub.update();
_vehicle_status_nav_state_sub.update();
if (_vehicle_status_sub.updated()) {
vehicle_status_s vehicle_status;
if (_vehicle_status_sub.copy(&vehicle_status)) {
_armed = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED);
_nav_state = vehicle_status.nav_state;
}
}
if (_actuator_controls_status_sub.updated()) {
actuator_controls_status_s controls_status;
@@ -290,7 +296,7 @@ void FwAutotuneAttitudeControl::updateStateMachine(hrt_abstime now)
mavlink_log_info(&_mavlink_log_pub, "Autotune started");
_state = state::init;
_state_start_time = now;
_start_flight_mode = _vehicle_status_nav_state_sub.get();
_start_flight_mode = _nav_state;
}
break;
@@ -423,7 +429,7 @@ void FwAutotuneAttitudeControl::updateStateMachine(hrt_abstime now)
break;
case state::wait_for_disarm:
if (!(_vehicle_status_armed_state_sub.get() == vehicle_status_s::ARMING_STATE_ARMED)) {
if (!_armed) {
saveGainsToParams();
_state = state::complete;
_state_start_time = now;
@@ -475,7 +481,7 @@ void FwAutotuneAttitudeControl::updateStateMachine(hrt_abstime now)
if (_state != state::wait_for_disarm && _state != state::idle && _state != state::fail && _state != state::complete) {
if (now - _state_start_time > 20_s
|| (_param_fw_at_man_aux.get() && !_aux_switch_en)
|| _start_flight_mode != _vehicle_status_nav_state_sub.get()) {
|| _start_flight_mode != _nav_state) {
orb_advert_t mavlink_log_pub = nullptr;
mavlink_log_critical(&mavlink_log_pub, "Autotune aborted before finishing");
_state = state::fail;
@@ -114,8 +114,7 @@ private:
uORB::Subscription _actuator_controls_status_sub;
uORB::Subscription _manual_control_setpoint_sub{ORB_ID(manual_control_setpoint)};
uORB::Subscription _vehicle_angular_velocity_sub{ORB_ID(vehicle_angular_velocity)};
uORB::SubscriptionSelection<&vehicle_status_s::arming_state> _vehicle_status_armed_state_sub{ORB_ID(vehicle_status)};
uORB::SubscriptionSelection<&vehicle_status_s::nav_state> _vehicle_status_nav_state_sub{ORB_ID(vehicle_status)};
uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)};
uORB::PublicationData<autotune_attitude_control_status_s> _autotune_attitude_control_status_pub{ORB_ID(autotune_attitude_control_status)};
@@ -143,6 +142,8 @@ private:
uint8_t _max_steps{5};
int8_t _signal_sign{0};
bool _armed{false};
uint8_t _nav_state{0};
uint8_t _start_flight_mode{0};
bool _aux_switch_en{false};
@@ -709,8 +709,24 @@ FixedwingPositionControl::set_control_mode_current(const hrt_abstime &now)
_skipping_takeoff_detection = false;
if (((_control_mode.flag_control_auto_enabled && _control_mode.flag_control_position_enabled) ||
_control_mode.flag_control_offboard_enabled) && _position_setpoint_current_valid) {
if (_control_mode.flag_control_offboard_enabled && _position_setpoint_current_valid) {
if (_control_mode.flag_control_position_enabled) {
if (PX4_ISFINITE(_pos_sp_triplet.current.vx) && PX4_ISFINITE(_pos_sp_triplet.current.vy)
&& PX4_ISFINITE(_pos_sp_triplet.current.vz)) {
// Offboard position with velocity setpoints
_control_mode_current = FW_POSCTRL_MODE_AUTO_PATH;
return;
} else {
// Offboard position setpoint only
_control_mode_current = FW_POSCTRL_MODE_AUTO;
return;
}
}
}
if ((_control_mode.flag_control_auto_enabled && _control_mode.flag_control_position_enabled)
&& _position_setpoint_current_valid) {
if (_pos_sp_triplet.current.type == position_setpoint_s::SETPOINT_TYPE_TAKEOFF) {
@@ -1097,17 +1113,7 @@ FixedwingPositionControl::control_auto_position(const float control_interval, co
_npfg.setAirspeedNom(target_airspeed * _eas2tas);
_npfg.setAirspeedMax(_param_fw_airspd_max.get() * _eas2tas);
if (_control_mode.flag_control_offboard_enabled && PX4_ISFINITE(pos_sp_curr.vx) && PX4_ISFINITE(pos_sp_curr.vy)) {
// Navigate directly on position setpoint and path tangent
matrix::Vector2f velocity_2d(pos_sp_curr.vx, pos_sp_curr.vy);
float curvature = PX4_ISFINITE(_pos_sp_triplet.current.loiter_radius) ? 1 / _pos_sp_triplet.current.loiter_radius :
0.0f;
navigatePathTangent(curr_pos_local, curr_wp_local, velocity_2d.normalized(), ground_speed,
_wind_vel, curvature);
} else {
navigateWaypoints(prev_wp_local, curr_wp_local, curr_pos_local, ground_speed, _wind_vel);
}
navigateWaypoints(prev_wp_local, curr_wp_local, curr_pos_local, ground_speed, _wind_vel);
_att_sp.roll_body = _npfg.getRollSetpoint();
target_airspeed = _npfg.getAirspeedRef() / _eas2tas;
@@ -1282,6 +1288,57 @@ FixedwingPositionControl::control_auto_loiter(const float control_interval, cons
_param_climbrate_target.get());
}
void
FixedwingPositionControl::control_auto_path(const float control_interval, const Vector2d &curr_pos,
const Vector2f &ground_speed, const position_setpoint_s &pos_sp_curr)
{
float tecs_fw_thr_min;
float tecs_fw_thr_max;
if (pos_sp_curr.gliding_enabled) {
/* enable gliding with this waypoint */
_tecs.set_speed_weight(2.0f);
tecs_fw_thr_min = 0.0;
tecs_fw_thr_max = 0.0;
} else {
tecs_fw_thr_min = _param_fw_thr_min.get();
tecs_fw_thr_max = _param_fw_thr_max.get();
}
// waypoint is a plain navigation waypoint
float target_airspeed = adapt_airspeed_setpoint(control_interval, pos_sp_curr.cruising_speed,
_param_fw_airspd_min.get(), ground_speed);
Vector2f curr_pos_local{_local_pos.x, _local_pos.y};
Vector2f curr_wp_local = _global_local_proj_ref.project(pos_sp_curr.lat, pos_sp_curr.lon);
_npfg.setAirspeedNom(target_airspeed * _eas2tas);
_npfg.setAirspeedMax(_param_fw_airspd_max.get() * _eas2tas);
// Navigate directly on position setpoint and path tangent
matrix::Vector2f velocity_2d(pos_sp_curr.vx, pos_sp_curr.vy);
float curvature = PX4_ISFINITE(_pos_sp_triplet.current.loiter_radius) ? 1 / _pos_sp_triplet.current.loiter_radius :
0.0f;
navigatePathTangent(curr_pos_local, curr_wp_local, velocity_2d.normalized(), ground_speed, _wind_vel, curvature);
_att_sp.roll_body = _npfg.getRollSetpoint();
target_airspeed = _npfg.getAirspeedRef() / _eas2tas;
_att_sp.yaw_body = _yaw; // yaw is not controlled, so set setpoint to current yaw
tecs_update_pitch_throttle(control_interval,
pos_sp_curr.alt,
target_airspeed,
radians(_param_fw_p_lim_min.get()),
radians(_param_fw_p_lim_max.get()),
tecs_fw_thr_min,
tecs_fw_thr_max,
_param_sinkrate_target.get(),
_param_climbrate_target.get());
}
void
FixedwingPositionControl::control_auto_takeoff(const hrt_abstime &now, const float control_interval,
const Vector2d &global_position, const Vector2f &ground_speed, const position_setpoint_s &pos_sp_curr)
@@ -2345,6 +2402,11 @@ FixedwingPositionControl::Run()
break;
}
case FW_POSCTRL_MODE_AUTO_PATH: {
control_auto_path(control_interval, curr_pos, ground_speed, _pos_sp_triplet.current);
break;
}
case FW_POSCTRL_MODE_AUTO_TAKEOFF: {
control_auto_takeoff(_local_pos.timestamp, control_interval, curr_pos, ground_speed, _pos_sp_triplet.current);
break;
@@ -243,6 +243,7 @@ private:
FW_POSCTRL_MODE_AUTO_TAKEOFF,
FW_POSCTRL_MODE_AUTO_LANDING_STRAIGHT,
FW_POSCTRL_MODE_AUTO_LANDING_CIRCULAR,
FW_POSCTRL_MODE_AUTO_PATH,
FW_POSCTRL_MODE_MANUAL_POSITION,
FW_POSCTRL_MODE_MANUAL_ALTITUDE,
FW_POSCTRL_MODE_OTHER
@@ -585,6 +586,18 @@ private:
void control_auto_loiter(const float control_interval, const Vector2d &curr_pos, const Vector2f &ground_speed,
const position_setpoint_s &pos_sp_prev, const position_setpoint_s &pos_sp_curr, const position_setpoint_s &pos_sp_next);
/**
* @brief Vehicle control for following a path.
*
* @param control_interval Time since last position control call [s]
* @param curr_pos Current 2D local position vector of vehicle [m]
* @param ground_speed Local 2D ground speed of vehicle [m/s]
* @param pos_sp_prev previous position setpoint
* @param pos_sp_curr current position setpoint
*/
void control_auto_path(const float control_interval, const Vector2d &curr_pos, const Vector2f &ground_speed,
const position_setpoint_s &pos_sp_curr);
/**
* @brief Controls a desired airspeed, bearing, and height rate.
*
+1 -1
View File
@@ -51,7 +51,7 @@ void LoggedTopics::add_default_topics()
add_topic("airspeed", 1000);
add_optional_topic("airspeed_validated", 200);
add_optional_topic("autotune_attitude_control_status", 100);
add_optional_topic("camera_capture");
add_topic("camera_capture");
add_optional_topic("camera_trigger");
add_topic("cellular_status", 200);
add_topic("commander_state");
@@ -96,7 +96,13 @@ void McAutotuneAttitudeControl::Run()
return;
}
_vehicle_status_arming_state_sub.update();
if (_vehicle_status_sub.updated()) {
vehicle_status_s vehicle_status;
if (_vehicle_status_sub.copy(&vehicle_status)) {
_armed = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED);
}
}
if (_actuator_controls_status_sub.updated()) {
actuator_controls_status_s controls_status;
@@ -393,7 +399,7 @@ void McAutotuneAttitudeControl::updateStateMachine(hrt_abstime now)
break;
case state::wait_for_disarm:
if (!(_vehicle_status_arming_state_sub.get() == vehicle_status_s::ARMING_STATE_ARMED)) {
if (!_armed) {
saveGainsToParams();
_state = state::complete;
_state_start_time = now;
@@ -108,7 +108,7 @@ private:
uORB::Subscription _actuator_controls_status_sub{ORB_ID(actuator_controls_status_0)};
uORB::Subscription _manual_control_setpoint_sub{ORB_ID(manual_control_setpoint)};
uORB::Subscription _vehicle_angular_velocity_sub{ORB_ID(vehicle_angular_velocity)};
uORB::SubscriptionSelection<&vehicle_status_s::arming_state> _vehicle_status_arming_state_sub{ORB_ID(vehicle_status)};
uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)};
uORB::PublicationData<autotune_attitude_control_status_s> _autotune_attitude_control_status_pub{ORB_ID(autotune_attitude_control_status)};
@@ -136,6 +136,8 @@ private:
uint8_t _max_steps{5};
int8_t _signal_sign{0};
bool _armed{false};
matrix::Vector3f _kid{};
matrix::Vector3f _rate_k{};
matrix::Vector3f _rate_i{};
@@ -151,13 +151,18 @@ void MulticopterHoverThrustEstimator::Run()
perf_begin(_cycle_perf);
_vehicle_status_arming_state_sub.update();
if (_vehicle_status_sub.updated()) {
vehicle_status_s vehicle_status;
if (_vehicle_status_sub.copy(&vehicle_status)) {
_armed = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED);
}
}
const float dt = (local_pos.timestamp - _timestamp_last) * 1e-6f;
_timestamp_last = local_pos.timestamp;
if ((_vehicle_status_arming_state_sub.get() == vehicle_status_s::ARMING_STATE_ARMED) && _in_air && (dt > 0.001f)
&& (dt < 1.f) && PX4_ISFINITE(local_pos.az)) {
if (_armed && _in_air && (dt > 0.001f) && (dt < 1.f) && PX4_ISFINITE(local_pos.az)) {
_hover_thrust_ekf.predict(dt);
@@ -193,7 +198,7 @@ void MulticopterHoverThrustEstimator::Run()
} else {
_valid_hysteresis.set_state_and_update(false, hrt_absolute_time());
if (!(_vehicle_status_arming_state_sub.get() == vehicle_status_s::ARMING_STATE_ARMED)) {
if (!_armed) {
reset();
}
@@ -102,11 +102,12 @@ private:
uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s};
uORB::Subscription _vehicle_land_detected_sub{ORB_ID(vehicle_land_detected)};
uORB::SubscriptionSelection<&vehicle_status_s::arming_state> _vehicle_status_arming_state_sub{ORB_ID(vehicle_status)};
uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)};
uORB::Subscription _vehicle_local_position_setpoint_sub{ORB_ID(vehicle_local_position_setpoint)};
hrt_abstime _timestamp_last{0};
bool _armed{false};
bool _landed{false};
bool _in_air{false};
+61 -13
View File
@@ -79,7 +79,7 @@ void on_time(uxrSession *session, int64_t current_time, int64_t received_timesta
}
}
MicroddsClient::MicroddsClient(Transport transport, const char *device, int baudrate, const char *host,
MicroddsClient::MicroddsClient(Transport transport, const char *device, int baudrate, const char *agent_ip,
const char *port, bool localhost_only, bool custom_participant, const char *client_namespace) :
ModuleParams(nullptr),
_localhost_only(localhost_only), _custom_participant(custom_participant),
@@ -122,9 +122,11 @@ MicroddsClient::MicroddsClient(Transport transport, const char *device, int baud
#if defined(MICRODDS_CLIENT_UDP)
_transport_udp = new uxrUDPTransport();
strncpy(_port, port, PORT_MAX_LENGTH - 1);
strncpy(_agent_ip, agent_ip, AGENT_IP_MAX_LENGTH - 1);
if (_transport_udp) {
if (uxr_init_udp_transport(_transport_udp, UXR_IPv4, host, port)) {
if (uxr_init_udp_transport(_transport_udp, UXR_IPv4, _agent_ip, _port)) {
_comm = &_transport_udp->comm;
_fd = _transport_udp->platform.poll_fd.fd;
@@ -265,7 +267,7 @@ void MicroddsClient::run()
"</dds>"
);
if (ret < 0 || ret >= TOPIC_NAME_SIZE) {
if (ret < 0 || ret >= PARTICIPANT_XML_SIZE) {
PX4_ERR("create entities failed: namespace too long");
return;
}
@@ -546,8 +548,26 @@ int MicroddsClient::task_spawn(int argc, char *argv[])
int MicroddsClient::print_status()
{
PX4_INFO("Running, %s", _connected ? "connected" : "disconnected");
PX4_INFO("Payload tx: %i B/s", _last_payload_tx_rate);
PX4_INFO("Payload rx: %i B/s", _last_payload_rx_rate);
#if defined(MICRODDS_CLIENT_UDP)
if (_transport_udp != nullptr) {
PX4_INFO("Using transport: udp");
PX4_INFO("Agent IP: %s", _agent_ip);
PX4_INFO("Agent port: %s", _port);
}
#endif
if (_transport_serial != nullptr) {
PX4_INFO("Using transport: serial");
}
if (_connected) {
PX4_INFO("Payload tx: %i B/s", _last_payload_tx_rate);
PX4_INFO("Payload rx: %i B/s", _last_payload_rx_rate);
}
return 0;
}
@@ -558,19 +578,19 @@ MicroddsClient *MicroddsClient::instantiate(int argc, char *argv[])
int ch;
const char *myoptarg = nullptr;
char port[PORT_MAX_LENGTH] = {0};
char agent_ip[AGENT_IP_MAX_LENGTH] = {0};
#if defined(MICRODDS_CLIENT_UDP)
Transport transport = Transport::Udp;
#else
Transport transport = Transport::Serial;
#endif
const char *device = nullptr;
int baudrate = 921600;
const char *port = "8888";
bool localhost_only = false;
bool custom_participant = false;
const char *ip = "127.0.0.1";
const char *client_namespace = nullptr;//"px4";
@@ -605,11 +625,11 @@ MicroddsClient *MicroddsClient::instantiate(int argc, char *argv[])
#if defined(MICRODDS_CLIENT_UDP)
case 'h':
ip = myoptarg;
snprintf(agent_ip, AGENT_IP_MAX_LENGTH, "%s", myoptarg);
break;
case 'p':
port = myoptarg;
snprintf(port, PORT_MAX_LENGTH, "%s", myoptarg);
break;
case 'l':
@@ -636,6 +656,33 @@ MicroddsClient *MicroddsClient::instantiate(int argc, char *argv[])
}
}
#if defined(MICRODDS_CLIENT_UDP)
if (port[0] == '\0') {
// no port specified, use XRCE_DDS_PRT
int32_t port_i = 0;
param_get(param_find("XRCE_DDS_PRT"), &port_i);
if (port_i < 0 || port_i > 65535) {
PX4_ERR("port must be between 0 and 65535");
return nullptr;
}
snprintf(port, PORT_MAX_LENGTH, "%u", (uint16_t)port_i);
}
if (agent_ip[0] == '\0') {
// no agent ip specified, use XRCE_DDS_AG_IP
int32_t ip_i = 0;
param_get(param_find("XRCE_DDS_AG_IP"), &ip_i);
snprintf(agent_ip, AGENT_IP_MAX_LENGTH, "%u.%u.%u.%u", static_cast<uint8_t>(((ip_i) >> 24) & 0xff),
static_cast<uint8_t>(((ip_i) >> 16) & 0xff),
static_cast<uint8_t>(((ip_i) >> 8) & 0xff),
static_cast<uint8_t>(ip_i & 0xff));
}
#endif // MICRODDS_CLIENT_UDP
if (error_flag) {
return nullptr;
}
@@ -647,7 +694,8 @@ MicroddsClient *MicroddsClient::instantiate(int argc, char *argv[])
}
}
return new MicroddsClient(transport, device, baudrate, ip, port, localhost_only, custom_participant, client_namespace);
return new MicroddsClient(transport, device, baudrate, agent_ip, port, localhost_only, custom_participant,
client_namespace);
}
int MicroddsClient::print_usage(const char *reason)
@@ -671,8 +719,8 @@ $ microdds_client start -t udp -h 127.0.0.1 -p 15555
PRINT_MODULE_USAGE_PARAM_STRING('t', "udp", "serial|udp", "Transport protocol", true);
PRINT_MODULE_USAGE_PARAM_STRING('d', nullptr, "<file:dev>", "serial device", true);
PRINT_MODULE_USAGE_PARAM_INT('b', 0, 0, 3000000, "Baudrate (can also be p:<param_name>)", true);
PRINT_MODULE_USAGE_PARAM_STRING('h', "127.0.0.1", "<IP>", "Host IP", true);
PRINT_MODULE_USAGE_PARAM_INT('p', 8888, 0, 65535, "Remote Port", true);
PRINT_MODULE_USAGE_PARAM_STRING('h', nullptr, "<IP>", "Agent IP. If not provided, defaults to XRCE_DDS_AG_IP", true);
PRINT_MODULE_USAGE_PARAM_INT('p', -1, 0, 65535, "Agent listening port. If not provided, defaults to XRCE_DDS_PRT", true);
PRINT_MODULE_USAGE_PARAM_FLAG('l', "Restrict to localhost (use in combination with ROS_LOCALHOST_ONLY=1)", true);
PRINT_MODULE_USAGE_PARAM_FLAG('c', "Use custom participant config (profile_name=\"px4_participant\")", true);
PRINT_MODULE_USAGE_PARAM_STRING('n', nullptr, nullptr, "Client DDS namespace", true);
@@ -78,6 +78,17 @@ private:
const bool _custom_participant;
const char *_client_namespace;
// max port characters (5+'\0')
static const uint8_t PORT_MAX_LENGTH = 6;
// max agent ip characters (15+'\0')
static const uint8_t AGENT_IP_MAX_LENGTH = 16;
#if defined(CONFIG_NET) || defined(__PX4_POSIX)
char _port[PORT_MAX_LENGTH];
char _agent_ip[AGENT_IP_MAX_LENGTH];
#endif
SendTopicsSubs *_subs{nullptr};
RcvTopicsPubs *_pubs{nullptr};
+19 -21
View File
@@ -1,16 +1,3 @@
# parameters to auto start
# mode (normal, minimal)
# UDP port
# max rate
# DDS DOMAIN ID
#
# multiple instances?
module_name: Micro XRCE-DDS
serial_config:
- command: |
@@ -22,13 +9,8 @@ serial_config:
microdds_client start ${XRCE_DDS_ARGS}
port_config_param:
name: XRCE_DDS_${i}_CFG
name: XRCE_DDS_CFG
group: Micro XRCE-DDS
# MAVLink instances:
# 0: Telem1 Port (Telemetry Link)
# 1: Telem2 Port (Companion Link). Disabled by default to reduce RAM usage
# 2: Board-specific / no fixed function or port
#default: [TEL1, "", ""]
supports_networking: true
parameters:
@@ -46,7 +28,7 @@ parameters:
XRCE_DDS_KEY:
description:
short: XRCE DDS key
short: XRCE DDS Session key
long: |
XRCE DDS key, must be different from zero.
In a single agent - multi client configuration, each client
@@ -56,13 +38,29 @@ parameters:
reboot_required: true
default: 1
XRCE_DDS_UDP_PRT:
XRCE_DDS_PRT:
description:
short: Micro DDS UDP Port
long: |
If ethernet enabled and selected as configuration for micro DDS,
selected udp port will be set and used.
type: int32
min: 0
max: 65535
reboot_required: true
default: 8888
requires_ethernet: true
XRCE_DDS_AG_IP:
description:
short: Micro DDS Agent IP address
long: |
If ethernet enabled and selected as configuration for micro DDS,
selected Agent IP address will be set and used.
Decimal dot notation is not supported. IP address must be provided
in int32 format. For example, 192.168.1.2 is mapped to -1062731518;
127.0.0.1 is mapped to 2130706433.
type: int32
reboot_required: true
default: 2130706433
requires_ethernet: true
@@ -1,6 +1,6 @@
/****************************************************************************
*
* Copyright (c) 2022 PX4 Development Team. All rights reserved.
* Copyright (c) 2022-2023 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
@@ -50,6 +50,7 @@ void FeasibilityChecker::reset()
_is_landed = false;
_home_alt_msl = NAN;
_home_lat_lon = matrix::Vector2d((double)NAN, (double)NAN);
_current_position_lat_lon = matrix::Vector2d((double)NAN, (double)NAN);
_vehicle_type = VehicleType::RotaryWing;
_mission_validity_failed = false;
@@ -119,6 +120,12 @@ void FeasibilityChecker::updateData()
_is_landed = land_detected.landed;
}
if (_vehicle_global_position_sub.updated()) {
vehicle_global_position_s vehicle_global_position = {};
_vehicle_global_position_sub.copy(&vehicle_global_position);
_current_position_lat_lon = matrix::Vector2d(vehicle_global_position.lat, vehicle_global_position.lon);
}
param_t handle = param_find("FW_LND_ANG");
if (handle != PARAM_INVALID) {
@@ -131,12 +138,6 @@ void FeasibilityChecker::updateData()
param_get(handle, &_param_mis_dist_1wp);
}
handle = param_find("MIS_DIST_WPS");
if (handle != PARAM_INVALID) {
param_get(handle, &_param_mis_dist_wps);
}
handle = param_find("NAV_ACC_RAD");
if (handle != PARAM_INVALID) {
@@ -195,7 +196,7 @@ void FeasibilityChecker::doCommonChecks(mission_item_s &mission_item, const int
}
if (!_distance_first_waypoint_failed) {
_distance_first_waypoint_failed = !checkDistanceToFirstWaypoint(mission_item);
_distance_first_waypoint_failed = !checkHorizontalDistanceToFirstWaypoint(mission_item);
}
if (!_below_home_alt_failed) {
@@ -601,50 +602,44 @@ bool FeasibilityChecker::checkTakeoffLandAvailable()
}
bool FeasibilityChecker::checkDistanceToFirstWaypoint(mission_item_s &mission_item)
bool FeasibilityChecker::checkHorizontalDistanceToFirstWaypoint(mission_item_s &mission_item)
{
if (_param_mis_dist_1wp <= 0.0f || !_home_lat_lon.isAllFinite()) {
/* param not set, check is ok */
return true;
}
if (_param_mis_dist_1wp > FLT_EPSILON &&
(_current_position_lat_lon.isAllFinite()) && !_first_waypoint_found &&
MissionBlock::item_contains_position(mission_item)) {
if (!_first_waypoint_found && MissionBlock::item_contains_position(mission_item)) {
_first_waypoint_found = true;
float dist_to_1wp_from_current_pos = 1e6f;
/* check distance from current position to item */
float dist_to_1wp = get_distance_to_next_waypoint(
mission_item.lat, mission_item.lon,
_home_lat_lon(0), _home_lat_lon(1));
if (_current_position_lat_lon.isAllFinite()) {
dist_to_1wp_from_current_pos = get_distance_to_next_waypoint(
mission_item.lat, mission_item.lon,
_current_position_lat_lon(0), _current_position_lat_lon(1));
}
if (dist_to_1wp < _param_mis_dist_1wp) {
if (dist_to_1wp_from_current_pos < _param_mis_dist_1wp) {
return true;
} else {
/* item is too far from home */
/* item is too far from current position */
mavlink_log_critical(_mavlink_log_pub,
"First waypoint too far away: %dm, %d max\t",
(int)dist_to_1wp, (int)_param_mis_dist_1wp);
(int)dist_to_1wp_from_current_pos, (int)_param_mis_dist_1wp);
events::send<uint32_t, uint32_t>(events::ID("navigator_mis_first_wp_too_far"), {events::Log::Error, events::LogInternal::Info},
"First waypoint too far away: {1m} (maximum: {2m})", (uint32_t)dist_to_1wp, (uint32_t)_param_mis_dist_1wp);
"First waypoint too far away: {1m} (maximum: {2m})", (uint32_t)dist_to_1wp_from_current_pos,
(uint32_t)_param_mis_dist_1wp);
return false;
}
}
/* no waypoints found in mission, then we will not fly far away */
return true;
}
bool FeasibilityChecker::checkDistancesBetweenWaypoints(const mission_item_s &mission_item)
{
if (_param_mis_dist_wps <= 0.0f) {
/* param not set, check is ok */
return true;
}
/* check only items with valid lat/lon */
if (!MissionBlock::item_contains_position(mission_item)) {
return true;
@@ -658,24 +653,8 @@ bool FeasibilityChecker::checkDistancesBetweenWaypoints(const mission_item_s &mi
_last_lat, _last_lon);
if (dist_between_waypoints > _param_mis_dist_wps) {
/* distance between waypoints is too high */
mavlink_log_critical(_mavlink_log_pub,
"Distance between waypoints too far: %d meters, %d max.\t",
(int)dist_between_waypoints, (int)_param_mis_dist_wps);
events::send<uint32_t, uint32_t>(events::ID("navigator_mis_wp_dist_too_far"), {events::Log::Error, events::LogInternal::Info},
"Distance between waypoints too far: {1m}, (maximum: {2m})", (uint32_t)dist_between_waypoints,
(uint32_t)_param_mis_dist_wps);
return false;
/* do not allow waypoints that are literally on top of each other */
/* and do not allow condition gates that are at the same position as a navigation waypoint */
} else if (dist_between_waypoints < 0.05f &&
(mission_item.nav_cmd == NAV_CMD_CONDITION_GATE || _last_cmd == NAV_CMD_CONDITION_GATE)) {
if (dist_between_waypoints < 0.05f &&
(mission_item.nav_cmd == NAV_CMD_CONDITION_GATE || _last_cmd == NAV_CMD_CONDITION_GATE)) {
/* Waypoints and gate are at the exact same position, which indicates an
* invalid mission and makes calculating the direction from one waypoint
@@ -1,6 +1,6 @@
/****************************************************************************
*
* Copyright (c) 2022 PX4 Development Team. All rights reserved.
* Copyright (c) 2022-2023 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
@@ -37,6 +37,7 @@
#include <mathlib/mathlib.h>
#include <uORB/topics/home_position.h>
#include <uORB/topics/vehicle_status.h>
#include <uORB/topics/vehicle_global_position.h>
#include <uORB/topics/vehicle_land_detected.h>
#include <uORB/Subscription.hpp>
#include <px4_platform_common/module_params.h>
@@ -96,17 +97,18 @@ private:
uORB::Subscription _home_pos_sub{ORB_ID(home_position)};
uORB::Subscription _status_sub{ORB_ID(vehicle_status)};
uORB::Subscription _land_detector_sub{ORB_ID(vehicle_land_detected)};
uORB::Subscription _vehicle_global_position_sub{ORB_ID(vehicle_global_position)};
// parameters
float _param_fw_lnd_ang{0.f};
float _param_mis_dist_1wp{0.f};
float _param_mis_dist_wps{0.f};
float _param_nav_acc_rad{0.f};
int32_t _param_mis_takeoff_land_req{0};
bool _is_landed{false};
float _home_alt_msl{NAN};
matrix::Vector2d _home_lat_lon = matrix::Vector2d((double)NAN, (double)NAN);
matrix::Vector2d _current_position_lat_lon = matrix::Vector2d((double)NAN, (double)NAN);
VehicleType _vehicle_type{VehicleType::RotaryWing};
// internal flags to keep track of which checks failed
@@ -130,7 +132,7 @@ private:
int _landing_approach_index{-1};
mission_item_s _mission_item_previous = {};
// internal checkDistanceToFirstWaypoint variables
// internal checkHorizontalDistanceToFirstWaypoint variables
bool _first_waypoint_found{false};
// internal checkDistancesBetweenWaypoints variables
@@ -172,12 +174,12 @@ private:
bool checkLandPatternValidity(mission_item_s &mission_item, const int current_index, const int last_index);
/**
* @brief Check distance to first waypoint.
* @brief Check distance to first waypoint from current vehicle position (if available).
*
* @param mission_item The current mission item
* @return False if the check failed.
*/
bool checkDistanceToFirstWaypoint(mission_item_s &mission_item);
bool checkHorizontalDistanceToFirstWaypoint(mission_item_s &mission_item);
/**
* @brief Check distances between waypoints
@@ -1,6 +1,6 @@
/****************************************************************************
*
* Copyright (C) 2022 PX4 Development Team. All rights reserved.
* Copyright (C) 2022-2023 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
@@ -33,8 +33,6 @@
#include <gtest/gtest.h>
#include "FeasibilityChecker.hpp"
#include <uORB/topics/home_position.h>
#include <uORB/topics/vehicle_land_detected.h>
#include <lib/geo/geo.h>
@@ -67,6 +65,15 @@ public:
orb_publish(ORB_ID(home_position), home_pub, &home);
}
void publishCurrentPosition(double lat, double lon)
{
vehicle_global_position_s gpos = {};
gpos.lat = lat;
gpos.lon = lon;
orb_advert_t gpos_pub = orb_advertise(ORB_ID(vehicle_global_position), &gpos);
orb_publish(ORB_ID(vehicle_global_position), gpos_pub, &gpos);
}
void publishLanded(bool landed)
{
vehicle_land_detected_s land_detected = {};
@@ -123,73 +130,47 @@ TEST_F(FeasibilityCheckerTest, mission_item_validity)
ASSERT_EQ(ret, false);
}
TEST_F(FeasibilityCheckerTest, max_dist_between_waypoints)
{
TestFeasibilityChecker checker;
checker.publishLanded(true);
param_t param = param_handle(px4::params::MIS_DIST_WPS);
float max_dist = 1000.0f;
param_set(param, &max_dist);
checker.paramsChanged();
mission_item_s mission_item = {};
mission_item.nav_cmd = NAV_CMD_WAYPOINT;
checker.processNextItem(mission_item, 0, 3);
// waypoints are within limits, check should pass
double lat_new, lon_new;
waypoint_from_heading_and_distance(mission_item.lat, mission_item.lon, 0, 999, &lat_new, &lon_new);
mission_item.lat = lat_new;
mission_item.lon = lon_new;
checker.processNextItem(mission_item, 1, 3);
ASSERT_EQ(checker.someCheckFailed(), false);
// waypoints are above limits, check should fail
waypoint_from_heading_and_distance(mission_item.lat, mission_item.lon, 0, 1001, &lat_new, &lon_new);
mission_item.lat = lat_new;
mission_item.lon = lon_new;
checker.processNextItem(mission_item, 2, 3);
ASSERT_EQ(checker.someCheckFailed(), true);
}
TEST_F(FeasibilityCheckerTest, check_dist_first_waypoint)
{
// GIVEN: MIS_DIST_1WP set to 500m
TestFeasibilityChecker checker;
checker.publishLanded(true);
checker.publishHomePosition(0, 0, 0);
param_t param = param_handle(px4::params::MIS_DIST_1WP);
float max_dist = 500.0f;
param_set(param, &max_dist);
checker.paramsChanged();
mission_item_s mission_item = {};
mission_item.nav_cmd = NAV_CMD_WAYPOINT;
double lat_new, lon_new;
waypoint_from_heading_and_distance(mission_item.lat, mission_item.lon, 0, 501, &lat_new, &lon_new);
mission_item.lat = lat_new;
mission_item.lon = lon_new;
// GIVEN: no valid Current position
// THEN: always pass
checker.processNextItem(mission_item, 0, 1);
ASSERT_EQ(checker.someCheckFailed(), false);
ASSERT_EQ(checker.someCheckFailed(), true);
// BUT WHEN: valid current position, first WP 501m away from current pos
checker.reset();
checker.publishLanded(true);
checker.publishHomePosition(0, 0, 0);
checker.publishCurrentPosition(0, 0);
waypoint_from_heading_and_distance(0, 0, 0, 501, &lat_new, &lon_new);
mission_item.lat = lat_new;
mission_item.lon = lon_new;
// THEN: fail
checker.processNextItem(mission_item, 0, 1);
ASSERT_EQ(checker.someCheckFailed(), true);
// BUT WHEN: valid current position fist WP 499m away from current
checker.reset();
checker.publishLanded(true);
checker.publishCurrentPosition(0, 0);
waypoint_from_heading_and_distance(0, 0, 0, 499, &lat_new, &lon_new);
mission_item.lat = lat_new;
mission_item.lon = lon_new;
checker.processNextItem(mission_item, 0, 1);
// THEN: pass
checker.processNextItem(mission_item, 0, 1);
ASSERT_EQ(checker.someCheckFailed(), false);
}
-1
View File
@@ -242,7 +242,6 @@ private:
DEFINE_PARAMETERS(
(ParamFloat<px4::params::MIS_DIST_1WP>) _param_mis_dist_1wp,
(ParamFloat<px4::params::MIS_DIST_WPS>) _param_mis_dist_wps,
(ParamInt<px4::params::MIS_MNT_YAW_CTL>) _param_mis_mnt_yaw_ctl
)
+3 -19
View File
@@ -73,14 +73,14 @@ PARAM_DEFINE_FLOAT(MIS_TAKEOFF_ALT, 2.5f);
PARAM_DEFINE_INT32(MIS_TKO_LAND_REQ, 0);
/**
* Maximal horizontal distance from home to first waypoint
* Maximal horizontal distance from current position to first waypoint
*
* Failsafe check to prevent running mission stored from previous flight at a new takeoff location.
* Set a value of zero or less to disable. The mission will not be started if the current
* waypoint is more distant than MIS_DIST_1WP from the home position.
* waypoint is more distant than MIS_DIST_1WP from the current position.
*
* @unit m
* @min 0
* @min -1
* @max 10000
* @decimal 1
* @increment 100
@@ -88,22 +88,6 @@ PARAM_DEFINE_INT32(MIS_TKO_LAND_REQ, 0);
*/
PARAM_DEFINE_FLOAT(MIS_DIST_1WP, 900);
/**
* Maximal horizontal distance between waypoint
*
* Failsafe check to prevent running missions which are way too big.
* Set a value of zero or less to disable. The mission will not be started if any distance between
* two subsequent waypoints is greater than MIS_DIST_WPS.
*
* @unit m
* @min 0
* @max 10000
* @decimal 1
* @increment 100
* @group Mission
*/
PARAM_DEFINE_FLOAT(MIS_DIST_WPS, 900);
/**
* Enable yaw control of the mount. (Only affects multicopters and ROI mission items)
*
@@ -181,7 +181,13 @@ void VehicleIMU::Run()
ScheduleDelayed(_backup_schedule_timeout_us);
// check vehicle status for changes to armed state
_vehicle_control_mode_armed_sub.update();
if (_vehicle_control_mode_sub.updated()) {
vehicle_control_mode_s vehicle_control_mode;
if (_vehicle_control_mode_sub.copy(&vehicle_control_mode)) {
_armed = vehicle_control_mode.flag_armed;
}
}
// reset data gap monitor
_data_gap = false;
@@ -248,7 +254,7 @@ void VehicleIMU::Run()
}
if (_param_sens_imu_autocal.get() && !parameters_updated) {
if ((_vehicle_control_mode_armed_sub.get() || !_accel_calibration.calibrated() || !_gyro_calibration.calibrated())
if ((_armed || !_accel_calibration.calibrated() || !_gyro_calibration.calibrated())
&& (now_us > _in_flight_calibration_check_timestamp_last + 1_s)) {
SensorCalibrationUpdate();
@@ -109,8 +109,7 @@ private:
uORB::Subscription _sensor_accel_sub;
uORB::SubscriptionCallbackWorkItem _sensor_gyro_sub;
uORB::SubscriptionSelection<&vehicle_control_mode_s::flag_armed>
_vehicle_control_mode_armed_sub{ORB_ID(vehicle_control_mode)};
uORB::Subscription _vehicle_control_mode_sub{ORB_ID(vehicle_control_mode)};
calibration::Accelerometer _accel_calibration{};
calibration::Gyroscope _gyro_calibration{};
@@ -142,7 +142,7 @@ bool VehicleMagnetometer::ParametersUpdate(bool force)
_mag_comp_type = mag_comp_typ;
if (!_vehicle_control_mode_armed_sub.get()) {
if (!_armed) {
bool calibration_updated = false;
// update mag priority (CAL_MAGx_PRIO)
@@ -219,7 +219,7 @@ void VehicleMagnetometer::UpdateMagBiasEstimate()
_calibration_estimator_bias[mag_index] = bias;
// set initial mag calibration if disarmed, mag uncalibrated, and valid estimated bias available
if (_param_sens_mag_autocal.get() && !_vehicle_control_mode_armed_sub.get() && mag_bias_est.stable[mag_index]
if (_param_sens_mag_autocal.get() && !_armed && mag_bias_est.stable[mag_index]
&& (_calibration[mag_index].device_id() != 0) && !_calibration[mag_index].calibrated()) {
const Vector3f old_offset = _calibration[mag_index].offset();
@@ -263,7 +263,7 @@ void VehicleMagnetometer::UpdateMagCalibration()
static constexpr float min_var_allowed = magb_vref * 0.01f;
static constexpr float max_var_allowed = magb_vref * 500.f;
if (_vehicle_control_mode_armed_sub.get()) {
if (_armed) {
static constexpr uint8_t mag_cal_size = sizeof(_mag_cal) / sizeof(_mag_cal[0]);
for (int i = 0; i < math::min(_estimator_sensor_bias_subs.size(), mag_cal_size); i++) {
@@ -363,7 +363,7 @@ void VehicleMagnetometer::UpdatePowerCompensation()
{
if (_mag_comp_type != MagCompensationType::Disabled) {
// update power signal for mag compensation
if (_vehicle_control_mode_armed_sub.get() && (_mag_comp_type == MagCompensationType::Throttle)) {
if (_armed && (_mag_comp_type == MagCompensationType::Throttle)) {
vehicle_thrust_setpoint_s vehicle_thrust_setpoint;
if (_vehicle_thrust_setpoint_0_sub.update(&vehicle_thrust_setpoint)) {
@@ -403,8 +403,14 @@ void VehicleMagnetometer::Run()
const bool parameter_update = ParametersUpdate();
// update armed state
_vehicle_control_mode_armed_sub.update();
// check vehicle status for changes to armed state
if (_vehicle_control_mode_sub.updated()) {
vehicle_control_mode_s vehicle_control_mode;
if (_vehicle_control_mode_sub.copy(&vehicle_control_mode)) {
_armed = vehicle_control_mode.flag_armed;
}
}
UpdatePowerCompensation();
@@ -563,7 +569,7 @@ void VehicleMagnetometer::Run()
CheckFailover(time_now_us);
}
if (!_vehicle_control_mode_armed_sub.get()) {
if (!_armed) {
calcMagInconsistency();
}
@@ -113,8 +113,7 @@ private:
uORB::Subscription _vehicle_thrust_setpoint_0_sub{ORB_ID(vehicle_thrust_setpoint), 0};
uORB::Subscription _battery_status_sub{ORB_ID(battery_status), 0};
uORB::Subscription _magnetometer_bias_estimate_sub{ORB_ID(magnetometer_bias_estimate)};
uORB::SubscriptionSelection<&vehicle_control_mode_s::flag_armed>
_vehicle_control_mode_armed_sub{ORB_ID(vehicle_control_mode)};
uORB::Subscription _vehicle_control_mode_sub{ORB_ID(vehicle_control_mode)};
// Used to check, save and use learned magnetometer biases
uORB::SubscriptionMultiArray<estimator_sensor_bias_s> _estimator_sensor_bias_subs{ORB_ID::estimator_sensor_bias};
@@ -172,6 +171,8 @@ private:
int8_t _selected_sensor_sub_index{-1};
bool _armed{false};
DEFINE_PARAMETERS(
(ParamInt<px4::params::CAL_MAG_COMP_TYP>) _param_mag_comp_typ,
(ParamBool<px4::params::SENS_MAG_MODE>) _param_sens_mag_mode,
@@ -72,13 +72,19 @@ void BatterySimulator::Run()
updateCommands();
if (_vehicle_status_sub.updated()) {
vehicle_status_s vehicle_status;
if (_vehicle_status_sub.copy(&vehicle_status)) {
_armed = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED);
}
}
const hrt_abstime now_us = hrt_absolute_time();
const float discharge_interval_us = _param_sim_bat_drain.get() * 1000 * 1000;
_vehicle_status_arming_state_sub.update();
if (_vehicle_status_arming_state_sub.get() == vehicle_status_s::ARMING_STATE_ARMED) {
if (_armed) {
if (_last_integration_us != 0) {
_battery_percentage -= (now_us - _last_integration_us) / discharge_interval_us;
}
@@ -77,7 +77,7 @@ private:
uORB::Publication<battery_status_s> _battery_pub{ORB_ID(battery_status)};
uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s};
uORB::SubscriptionSelection<&vehicle_status_s::arming_state> _vehicle_status_arming_state_sub{ORB_ID(vehicle_status)};
uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)};
uORB::Subscription _vehicle_command_sub{ORB_ID(vehicle_command)};
uORB::Publication<vehicle_command_ack_s> _command_ack_pub{ORB_ID(vehicle_command_ack)};
@@ -86,6 +86,7 @@ private:
uint64_t _last_integration_us{0};
float _battery_percentage{1.f};
bool _armed{false};
bool _force_empty_battery{false};