1 #include "AP_RCProtocol_config.h"
3 #if AP_RCPROTOCOL_UDP_ENABLED
5 #include "AP_RCProtocol_UDP.h"
7 #include <AP_HAL/AP_HAL.h>
8 #include <AP_Vehicle/AP_Vehicle_Type.h>
11 #if AP_RCPROTOCOL_FDM_ENABLED
12 #include "AP_RCProtocol_FDM.h"
15 extern const AP_HAL::HAL
& hal
;
17 void AP_RCProtocol_UDP::set_default_pwm_input_values()
28 #if APM_BUILD_TYPE(APM_BUILD_Rover)
29 // set correct default throttle for rover (allowing for reverse)
31 #elif APM_BUILD_TYPE(APM_BUILD_ArduSub) || APM_BUILD_TYPE(APM_BUILD_Blimp)
32 for(uint8_t i
= 0; i
< 8; i
++) {
40 bool AP_RCProtocol_UDP::init()
42 const auto sitl
= AP::sitl();
43 if (sitl
== nullptr) {
46 if (!rc_in
.reuseaddress()) {
49 if (!rc_in
.bind("0.0.0.0", sitl
->rcin_port
)) {
52 if (!rc_in
.set_blocking(false)) {
55 if (!rc_in
.set_cloexec()) {
59 set_default_pwm_input_values();
64 void AP_RCProtocol_UDP::update()
66 #if AP_RCPROTOCOL_FDM_ENABLED
67 // yield to the FDM backend if it is getting data
68 if (fdm_backend
->active()) {
80 read_all_socket_input();
82 #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
83 const auto sitl
= AP::sitl();
84 if (sitl
== nullptr) {
88 if (sitl
->rc_fail
== SITL::SIM::SITL_RCFail_NoPulses
) {
93 // simulate RC input at 50Hz
94 if (AP_HAL::millis() - last_input_ms
< 20) {
97 last_input_ms
= AP_HAL::millis();
109 check for a SITL RC input packet
111 void AP_RCProtocol_UDP::read_all_socket_input(void)
116 uint8_t pwm_pkt_num_channels
= 0;
118 ssize_t receive_size
= 1; // lies!
120 while (receive_size
> 0) {
121 receive_size
= rc_in
.recv(&pwm_pkt
, sizeof(pwm_pkt
), 0);
123 switch (receive_size
) {
128 pwm_pkt_num_channels
= receive_size
/2;
131 fprintf(stderr
, "Malformed SITL RC input (%ld)", (long)receive_size
);
138 ::fprintf(stderr
, "Read %u rc inputs\n", count
);
141 #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
142 const auto sitl
= AP::sitl();
143 if (sitl
== nullptr) {
147 // convert last packet received into pwm values
148 switch (sitl
->rc_fail
) {
149 case SITL::SIM::SITL_RCFail_Throttle950
:
150 // discard anything we just read from the "receiver" and set
151 // values to bind values:
152 for (uint8_t i
=0; i
<ARRAY_SIZE(pwm_input
); i
++) {
153 pwm_input
[i
] = 1500; // centre all inputs
155 pwm_input
[2] = 950; // reset throttle (assumed to be on channel 3...)
157 case SITL::SIM::SITL_RCFail_NoPulses
:
158 // see also code in ::update
160 case SITL::SIM::SITL_RCFail_None
:
165 if (pwm_pkt_num_channels
== 0) {
168 for (uint8_t i
=0; i
<pwm_pkt_num_channels
; i
++) {
169 // setup the pwm input for the RC channel inputs
170 const uint16_t pwm
= pwm_pkt
.pwm
[i
];
172 // 0 means "ignore this value"
177 num_channels
= pwm_pkt_num_channels
; // or ARRAY_SIZE(pwm_input)?
180 #endif // AP_RCPROTOCOL_UDP_ENABLED