1
1
/* ***************************************************************************
2
2
*
3
- * Copyright (c) 2012-2015 PX4 Development Team. All rights reserved.
3
+ * Copyright (c) 2012-2019 PX4 Development Team. All rights reserved.
4
4
*
5
5
* Redistribution and use in source and binary forms, with or without
6
6
* modification, are permitted provided that the following conditions
68
68
69
69
#include < rc/dsm.h>
70
70
71
+ #include < lib/mathlib/mathlib.h>
71
72
#include < lib/mixer/mixer.h>
72
73
#include < perf/perf_counter.h>
73
74
#include < systemlib/err.h>
74
75
#include < parameters/param.h>
75
76
#include < circuit_breaker/circuit_breaker.h>
76
77
#include < systemlib/mavlink_log.h>
77
78
79
+ #include < uORB/Subscription.hpp>
78
80
#include < uORB/topics/actuator_controls.h>
79
81
#include < uORB/topics/actuator_outputs.h>
80
82
#include < uORB/topics/actuator_armed.h>
101
103
#define PX4IO_REBOOT_BOOTLOADER _IOC (0xff00 , 2 )
102
104
#define PX4IO_CHECK_CRC _IOC (0xff00 , 3 )
103
105
104
- #define UPDATE_INTERVAL_MIN 2 // 2 ms -> 500 Hz
106
+ static constexpr unsigned UPDATE_INTERVAL_MIN{2 }; // 2 ms -> 500 Hz
107
+ static constexpr unsigned UPDATE_INTERVAL_MAX{100 }; // 100 ms -> 10 Hz
108
+
105
109
#define ORB_CHECK_INTERVAL 200000 // 200 ms -> 5 Hz
106
110
#define IO_POLL_INTERVAL 20000 // 20 ms -> 50 Hz
107
111
@@ -245,14 +249,16 @@ class PX4IO : public cdev::CDev
245
249
246
250
/* subscribed topics */
247
251
int _t_actuator_controls_0; // /< actuator controls group 0 topic
248
- int _t_actuator_controls_1; // /< actuator controls group 1 topic
249
- int _t_actuator_controls_2; // /< actuator controls group 2 topic
250
- int _t_actuator_controls_3; // /< actuator controls group 3 topic
251
- int _t_actuator_armed; // /< system armed control topic
252
- int _t_vehicle_control_mode;// /< vehicle control mode topic
253
- int _t_param; // /< parameter update topic
252
+
253
+ uORB::Subscription _t_actuator_controls_1{ORB_ID (actuator_controls_1)}; // /< actuator controls group 1 topic
254
+ uORB::Subscription _t_actuator_controls_2{ORB_ID (actuator_controls_2)};; // /< actuator controls group 2 topic
255
+ uORB::Subscription _t_actuator_controls_3{ORB_ID (actuator_controls_3)};; // /< actuator controls group 3 topic
256
+ uORB::Subscription _t_actuator_armed{ORB_ID (actuator_armed)}; // /< system armed control topic
257
+ uORB::Subscription _t_vehicle_control_mode{ORB_ID (vehicle_control_mode)}; // /< vehicle control mode topic
258
+ uORB::Subscription _t_param{ORB_ID (parameter_update)}; // /< parameter update topic
259
+ uORB::Subscription _t_vehicle_command{ORB_ID (vehicle_command)}; // /< vehicle command topic
260
+
254
261
bool _param_update_force; // /< force a parameter update
255
- int _t_vehicle_command; // /< vehicle command topic
256
262
257
263
/* advertised topics */
258
264
orb_advert_t _to_input_rc; // /< rc inputs from io
@@ -466,14 +472,7 @@ PX4IO::PX4IO(device::Device *interface) :
466
472
_last_written_arming_s(0 ),
467
473
_last_written_arming_c(0 ),
468
474
_t_actuator_controls_0(-1 ),
469
- _t_actuator_controls_1(-1 ),
470
- _t_actuator_controls_2(-1 ),
471
- _t_actuator_controls_3(-1 ),
472
- _t_actuator_armed(-1 ),
473
- _t_vehicle_control_mode(-1 ),
474
- _t_param(-1 ),
475
475
_param_update_force(false ),
476
- _t_vehicle_command(-1 ),
477
476
_to_input_rc(nullptr ),
478
477
_to_outputs(nullptr ),
479
478
_to_servorail(nullptr ),
@@ -683,20 +682,17 @@ PX4IO::init()
683
682
* remains untouched (so manual override is still available).
684
683
*/
685
684
686
- int safety_sub = orb_subscribe (ORB_ID (actuator_armed));
685
+ uORB::Subscription actuator_armed_sub{ORB_ID (actuator_armed)};
686
+
687
687
/* fill with initial values, clear updated flag */
688
- struct actuator_armed_s safety ;
688
+ actuator_armed_s actuator_armed{} ;
689
689
uint64_t try_start_time = hrt_absolute_time ();
690
- bool updated = false ;
691
690
692
691
/* keep checking for an update, ensure we got a arming information,
693
692
not something that was published a long time ago. */
694
693
do {
695
- orb_check (safety_sub, &updated);
696
-
697
- if (updated) {
698
- /* got data, copy and exit loop */
699
- orb_copy (ORB_ID (actuator_armed), safety_sub, &safety);
694
+ if (actuator_armed_sub.update (&actuator_armed)) {
695
+ // updated data, exit loop
700
696
break ;
701
697
}
702
698
@@ -746,11 +742,7 @@ PX4IO::init()
746
742
747
743
/* spin here until IO's state has propagated into the system */
748
744
do {
749
- orb_check (safety_sub, &updated);
750
-
751
- if (updated) {
752
- orb_copy (ORB_ID (actuator_armed), safety_sub, &safety);
753
- }
745
+ actuator_armed_sub.update (&actuator_armed);
754
746
755
747
/* wait 50 ms */
756
748
px4_usleep (50000 );
@@ -762,13 +754,13 @@ PX4IO::init()
762
754
}
763
755
764
756
/* re-send if necessary */
765
- if (!safety .force_failsafe ) {
757
+ if (!actuator_armed .force_failsafe ) {
766
758
orb_publish (ORB_ID (vehicle_command), pub, &vcmd);
767
759
PX4_WARN (" re-sending flight termination cmd" );
768
760
}
769
761
770
762
/* keep waiting for state change for 2 s */
771
- } while (!safety .force_failsafe );
763
+ } while (!actuator_armed .force_failsafe );
772
764
}
773
765
774
766
/* send command to arm system via command API */
@@ -781,11 +773,7 @@ PX4IO::init()
781
773
782
774
/* spin here until IO's state has propagated into the system */
783
775
do {
784
- orb_check (safety_sub, &updated);
785
-
786
- if (updated) {
787
- orb_copy (ORB_ID (actuator_armed), safety_sub, &safety);
788
- }
776
+ actuator_armed_sub.update (&actuator_armed);
789
777
790
778
/* wait 50 ms */
791
779
px4_usleep (50000 );
@@ -797,13 +785,13 @@ PX4IO::init()
797
785
}
798
786
799
787
/* re-send if necessary */
800
- if (!safety .armed ) {
788
+ if (!actuator_armed .armed ) {
801
789
orb_publish (ORB_ID (vehicle_command), pub, &vcmd);
802
790
PX4_WARN (" re-sending arm cmd" );
803
791
}
804
792
805
793
/* keep waiting for state change for 2 s */
806
- } while (!safety .armed );
794
+ } while (!actuator_armed .armed );
807
795
808
796
/* Indicate restart type is in-flight */
809
797
sys_restart_val = DM_INIT_REASON_IN_FLIGHT;
@@ -902,23 +890,9 @@ PX4IO::task_main()
902
890
*/
903
891
_t_actuator_controls_0 = orb_subscribe (ORB_ID (actuator_controls_0));
904
892
orb_set_interval (_t_actuator_controls_0, 20 ); /* default to 50Hz */
905
- _t_actuator_controls_1 = orb_subscribe (ORB_ID (actuator_controls_1));
906
- orb_set_interval (_t_actuator_controls_1, 33 ); /* default to 30Hz */
907
- _t_actuator_controls_2 = orb_subscribe (ORB_ID (actuator_controls_2));
908
- orb_set_interval (_t_actuator_controls_2, 33 ); /* default to 30Hz */
909
- _t_actuator_controls_3 = orb_subscribe (ORB_ID (actuator_controls_3));
910
- orb_set_interval (_t_actuator_controls_3, 33 ); /* default to 30Hz */
911
- _t_actuator_armed = orb_subscribe (ORB_ID (actuator_armed));
912
- _t_vehicle_control_mode = orb_subscribe (ORB_ID (vehicle_control_mode));
913
- _t_param = orb_subscribe (ORB_ID (parameter_update));
914
- _t_vehicle_command = orb_subscribe (ORB_ID (vehicle_command));
915
-
916
- if ((_t_actuator_controls_0 < 0 ) ||
917
- (_t_actuator_armed < 0 ) ||
918
- (_t_vehicle_control_mode < 0 ) ||
919
- (_t_param < 0 ) ||
920
- (_t_vehicle_command < 0 )) {
921
- warnx (" subscription(s) failed" );
893
+
894
+ if (_t_actuator_controls_0 < 0 ) {
895
+ PX4_ERR (" actuator subscription failed" );
922
896
goto out;
923
897
}
924
898
@@ -940,13 +914,7 @@ PX4IO::task_main()
940
914
941
915
/* adjust update interval */
942
916
if (_update_interval != 0 ) {
943
- if (_update_interval < UPDATE_INTERVAL_MIN) {
944
- _update_interval = UPDATE_INTERVAL_MIN;
945
- }
946
-
947
- if (_update_interval > 100 ) {
948
- _update_interval = 100 ;
949
- }
917
+ _update_interval = math::constrain (_update_interval, UPDATE_INTERVAL_MIN, UPDATE_INTERVAL_MAX);
950
918
951
919
orb_set_interval (_t_actuator_controls_0, _update_interval);
952
920
/*
@@ -995,10 +963,10 @@ PX4IO::task_main()
995
963
bool updated = false ;
996
964
997
965
/* arming state */
998
- orb_check (_t_actuator_armed, & updated);
966
+ updated = _t_actuator_armed. updated ( );
999
967
1000
968
if (!updated) {
1001
- orb_check (_t_vehicle_control_mode, & updated);
969
+ updated = _t_vehicle_control_mode. updated ( );
1002
970
}
1003
971
1004
972
if (updated) {
@@ -1010,15 +978,10 @@ PX4IO::task_main()
1010
978
/* run at 5Hz */
1011
979
orb_check_last = now;
1012
980
1013
- /* check updates on uORB topics and handle it */
1014
- bool updated = false ;
1015
-
1016
981
/* vehicle command */
1017
- orb_check (_t_vehicle_command, &updated);
1018
-
1019
- if (updated) {
1020
- struct vehicle_command_s cmd;
1021
- orb_copy (ORB_ID (vehicle_command), _t_vehicle_command, &cmd);
982
+ if (_t_vehicle_command.updated ()) {
983
+ vehicle_command_s cmd{};
984
+ _t_vehicle_command.copy (&cmd);
1022
985
1023
986
// Check for a DSM pairing command
1024
987
if (((unsigned int )cmd.command == vehicle_command_s::VEHICLE_CMD_START_RX_PAIR) && ((int )cmd.param1 == 0 )) {
@@ -1031,12 +994,10 @@ PX4IO::task_main()
1031
994
*
1032
995
* XXX this may be a bit spammy
1033
996
*/
1034
- orb_check (_t_param, &updated);
1035
-
1036
- if (updated || _param_update_force) {
997
+ if (_t_param.updated () || _param_update_force) {
1037
998
_param_update_force = false ;
1038
999
parameter_update_s pupdate;
1039
- orb_copy ( ORB_ID (parameter_update), _t_param, &pupdate);
1000
+ _t_param. copy ( &pupdate);
1040
1001
1041
1002
if (!_rc_handling_disabled) {
1042
1003
/* re-upload RC input config as it may have changed */
@@ -1295,8 +1256,7 @@ PX4IO::io_set_control_groups()
1295
1256
int
1296
1257
PX4IO::io_set_control_state (unsigned group)
1297
1258
{
1298
- actuator_controls_s controls; // /< actuator outputs
1299
- uint16_t regs[_max_actuators];
1259
+ actuator_controls_s controls{}; // /< actuator outputs
1300
1260
1301
1261
/* get controls */
1302
1262
bool changed = false ;
@@ -1312,31 +1272,16 @@ PX4IO::io_set_control_state(unsigned group)
1312
1272
}
1313
1273
break ;
1314
1274
1315
- case 1 : {
1316
- orb_check (_t_actuator_controls_1, &changed);
1317
-
1318
- if (changed) {
1319
- orb_copy (ORB_ID (actuator_controls_1), _t_actuator_controls_1, &controls);
1320
- }
1321
- }
1275
+ case 1 :
1276
+ changed = _t_actuator_controls_1.update (&controls);
1322
1277
break ;
1323
1278
1324
- case 2 : {
1325
- orb_check (_t_actuator_controls_2, &changed);
1326
-
1327
- if (changed) {
1328
- orb_copy (ORB_ID (actuator_controls_2), _t_actuator_controls_2, &controls);
1329
- }
1330
- }
1279
+ case 2 :
1280
+ changed = _t_actuator_controls_2.update (&controls);
1331
1281
break ;
1332
1282
1333
- case 3 : {
1334
- orb_check (_t_actuator_controls_3, &changed);
1335
-
1336
- if (changed) {
1337
- orb_copy (ORB_ID (actuator_controls_3), _t_actuator_controls_3, &controls);
1338
- }
1339
- }
1283
+ case 3 :
1284
+ changed = _t_actuator_controls_3.update (&controls);
1340
1285
break ;
1341
1286
}
1342
1287
@@ -1351,17 +1296,11 @@ PX4IO::io_set_control_state(unsigned group)
1351
1296
controls.control [3 ] = 1 .0f ;
1352
1297
}
1353
1298
1354
- for ( unsigned i = 0 ; i < _max_controls; i++) {
1299
+ uint16_t regs[_max_actuators];
1355
1300
1301
+ for (unsigned i = 0 ; i < _max_controls; i++) {
1356
1302
/* ensure FLOAT_TO_REG does not produce an integer overflow */
1357
- float ctrl = controls.control [i];
1358
-
1359
- if (ctrl < -1 .0f ) {
1360
- ctrl = -1 .0f ;
1361
-
1362
- } else if (ctrl > 1 .0f ) {
1363
- ctrl = 1 .0f ;
1364
- }
1303
+ const float ctrl = math::constrain (controls.control [i], -1 .0f , 1 .0f );
1365
1304
1366
1305
regs[i] = FLOAT_TO_REG (ctrl);
1367
1306
}
@@ -1375,21 +1314,15 @@ PX4IO::io_set_control_state(unsigned group)
1375
1314
}
1376
1315
}
1377
1316
1378
-
1379
1317
int
1380
1318
PX4IO::io_set_arming_state ()
1381
1319
{
1382
- actuator_armed_s armed; // /< system armed state
1383
- vehicle_control_mode_s control_mode; // /< vehicle_control_mode
1384
-
1385
- int have_armed = orb_copy (ORB_ID (actuator_armed), _t_actuator_armed, &armed);
1386
- int have_control_mode = orb_copy (ORB_ID (vehicle_control_mode), _t_vehicle_control_mode, &control_mode);
1387
- _in_esc_calibration_mode = armed.in_esc_calibration_mode ;
1388
-
1389
1320
uint16_t set = 0 ;
1390
1321
uint16_t clear = 0 ;
1391
1322
1392
- if (have_armed == OK) {
1323
+ actuator_armed_s armed;
1324
+
1325
+ if (_t_actuator_armed.copy (&armed)) {
1393
1326
_in_esc_calibration_mode = armed.in_esc_calibration_mode ;
1394
1327
1395
1328
if (armed.armed || _in_esc_calibration_mode) {
@@ -1433,7 +1366,9 @@ PX4IO::io_set_arming_state()
1433
1366
}
1434
1367
}
1435
1368
1436
- if (have_control_mode == OK) {
1369
+ vehicle_control_mode_s control_mode;
1370
+
1371
+ if (_t_vehicle_control_mode.copy (&control_mode)) {
1437
1372
if (control_mode.flag_external_manual_override_ok ) {
1438
1373
set |= PX4IO_P_SETUP_ARMING_MANUAL_OVERRIDE_OK;
1439
1374
_override_available = true ;
@@ -2913,19 +2848,10 @@ PX4IO::write(file * /*filp*/, const char *buffer, size_t len)
2913
2848
int
2914
2849
PX4IO::set_update_rate (int rate)
2915
2850
{
2916
- int interval_ms = 1000 / rate;
2851
+ unsigned interval_ms = 1000 / rate;
2917
2852
2918
- if (interval_ms < UPDATE_INTERVAL_MIN) {
2919
- interval_ms = UPDATE_INTERVAL_MIN;
2920
- warnx (" update rate too high, limiting interval to %d ms (%d Hz)." , interval_ms, 1000 / interval_ms);
2921
- }
2922
-
2923
- if (interval_ms > 100 ) {
2924
- interval_ms = 100 ;
2925
- warnx (" update rate too low, limiting to %d ms (%d Hz)." , interval_ms, 1000 / interval_ms);
2926
- }
2853
+ _update_interval = math::constrain (interval_ms, UPDATE_INTERVAL_MIN, UPDATE_INTERVAL_MAX);
2927
2854
2928
- _update_interval = interval_ms;
2929
2855
return 0 ;
2930
2856
}
2931
2857
0 commit comments