PX4 Firmware
PX4 Autopilot Software http://px4.io
test_rc.c
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (C) 2012-2019 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file test_rc.c
36  * Tests RC input.
37  */
38 
39 #include <px4_platform_common/px4_config.h>
40 
41 #include <sys/types.h>
42 
43 #include <stdio.h>
44 #include <poll.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <fcntl.h>
48 #include <errno.h>
49 
50 #include <arch/board/board.h>
51 #include <drivers/drv_pwm_output.h>
52 #include <drivers/drv_rc_input.h>
53 #include <drivers/drv_hrt.h>
54 #include <systemlib/err.h>
55 
56 #include "tests_main.h"
57 
58 #include <math.h>
59 #include <float.h>
60 
61 int test_rc(int argc, char *argv[])
62 {
63  int _rc_sub = orb_subscribe(ORB_ID(input_rc));
64 
65  /* read low-level values from FMU or IO RC inputs (PPM, Spektrum, S.Bus) */
66  struct input_rc_s rc_input;
67  struct input_rc_s rc_last;
68  orb_copy(ORB_ID(input_rc), _rc_sub, &rc_input);
69  px4_usleep(100000);
70 
71  /* open PPM input and expect values close to the output values */
72 
73  bool rc_updated;
74  orb_check(_rc_sub, &rc_updated);
75 
76  PX4_INFO("Reading PPM values - press any key to abort");
77  PX4_INFO("This test guarantees: 10 Hz update rates, no glitches (channel values), no channel count changes.");
78 
79  if (rc_updated) {
80 
81  /* copy initial set */
82  for (unsigned i = 0; i < rc_input.channel_count; i++) {
83  rc_last.values[i] = rc_input.values[i];
84  }
85 
86  rc_last.channel_count = rc_input.channel_count;
87 
88  /* poll descriptor */
89  struct pollfd fds[2];
90  fds[0].fd = _rc_sub;
91  fds[0].events = POLLIN;
92  fds[1].fd = 0;
93  fds[1].events = POLLIN;
94 
95  while (true) {
96 
97  int ret = poll(fds, 2, 200);
98 
99  if (ret > 0) {
100 
101  if (fds[0].revents & POLLIN) {
102 
103  orb_copy(ORB_ID(input_rc), _rc_sub, &rc_input);
104 
105  /* go and check values */
106  for (unsigned i = 0; i < rc_input.channel_count; i++) {
107  if (abs(rc_input.values[i] - rc_last.values[i]) > 20) {
108  PX4_ERR("comparison fail: RC: %d, expected: %d", rc_input.values[i], rc_last.values[i]);
109  (void)orb_unsubscribe(_rc_sub);
110  return ERROR;
111  }
112 
113  rc_last.values[i] = rc_input.values[i];
114  }
115 
116  if (rc_last.channel_count != rc_input.channel_count) {
117  PX4_ERR("channel count mismatch: last: %d, now: %d", rc_last.channel_count, rc_input.channel_count);
118  (void)orb_unsubscribe(_rc_sub);
119  return ERROR;
120  }
121 
122  if (hrt_absolute_time() - rc_input.timestamp_last_signal > 100000) {
123  PX4_ERR("TIMEOUT, less than 10 Hz updates");
124  (void)orb_unsubscribe(_rc_sub);
125  return ERROR;
126  }
127 
128  } else {
129  /* key pressed, bye bye */
130  return 0;
131  }
132 
133  }
134  }
135 
136  } else {
137  PX4_ERR("failed reading RC input data");
138  return ERROR;
139  }
140 
141  PX4_INFO("PPM CONTINUITY TEST PASSED SUCCESSFULLY!");
142 
143  return 0;
144 }
int orb_copy(const struct orb_metadata *meta, int handle, void *buffer)
Definition: uORB.cpp:90
R/C input interface.
High-resolution timer with callouts and timekeeping.
int orb_subscribe(const struct orb_metadata *meta)
Definition: uORB.cpp:75
int test_rc(int argc, char *argv[])
Definition: test_rc.c:61
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
Definition: uORB.h:87
uint16_t values[18]
Definition: input_rc.h:76
uint32_t channel_count
Definition: input_rc.h:71
int orb_unsubscribe(int handle)
Definition: uORB.cpp:85
Simple error/warning functions, heavily inspired by the BSD functions of the same names...
Tests declaration file.
int orb_check(int handle, bool *updated)
Definition: uORB.cpp:95
Dual< Scalar, N > abs(const Dual< Scalar, N > &a)
Definition: Dual.hpp:196
uint64_t timestamp_last_signal
Definition: input_rc.h:70
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).