Skip to content

Commit cab9c9f

Browse files
committed
AP_Periph:add ap periph rc out current sampling and telemary support
1 parent 7ddb14c commit cab9c9f

File tree

6 files changed

+252
-0
lines changed

6 files changed

+252
-0
lines changed

Tools/AP_Periph/AP_Periph.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,11 @@ void AP_Periph_FW::init()
315315
#if AP_SCRIPTING_ENABLED
316316
scripting.init();
317317
#endif
318+
319+
#if AP_PERIPH_ACTUATOR_TELEM_ENABLED
320+
actuator_telem.init();
321+
#endif
322+
318323
start_ms = AP_HAL::millis();
319324
}
320325

@@ -505,6 +510,10 @@ void AP_Periph_FW::update()
505510
rcin_update();
506511
#endif
507512

513+
#if AP_PERIPH_ACTUATOR_TELEM_ENABLED
514+
actuator_telem.update();
515+
#endif
516+
508517
#if AP_PERIPH_BATTERY_BALANCE_ENABLED
509518
batt_balance_update();
510519
#endif

Tools/AP_Periph/AP_Periph.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "rc_in.h"
4242
#include "batt_balance.h"
4343
#include "battery_tag.h"
44+
#include "actuator_telem.h"
4445
#include "networking.h"
4546
#include "serial_options.h"
4647
#if AP_SIM_ENABLED
@@ -395,6 +396,10 @@ class AP_Periph_FW {
395396
#if AP_PERIPH_BATTERY_TAG_ENABLED
396397
BatteryTag battery_tag;
397398
#endif
399+
400+
#if AP_PERIPH_ACTUATOR_TELEM_ENABLED
401+
ActuatorTelem actuator_telem;
402+
#endif
398403

399404
#if AP_PERIPH_SERIAL_OPTIONS_ENABLED
400405
SerialOptions serial_options;

Tools/AP_Periph/Parameters.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,12 @@ const AP_Param::Info AP_Periph_FW::var_info[] = {
617617
GOBJECT(g_rcin, "RC", Parameters_RCIN),
618618
#endif
619619

620+
#if AP_PERIPH_ACTUATOR_TELEM_ENABLED
621+
// @Group: ACT
622+
// @Path: actuator_telem.cpp
623+
GOBJECT(actuator_telem, "ACT", ActuatorTelem),
624+
#endif
625+
620626
#if AP_PERIPH_BATTERY_BALANCE_ENABLED
621627
// @Group: BAL
622628
// @Path: batt_balance.cpp

Tools/AP_Periph/Parameters.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class Parameters {
7979
k_param_networking_periph,
8080
k_param_rpm_sensor,
8181
k_param_g_rcin,
82+
k_param_actuator_telem,
8283
k_param_sitl,
8384
k_param_ahrs,
8485
k_param_battery_balance,

Tools/AP_Periph/actuator_telem.cpp

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/*
2+
This program is free software: you can redistribute it and/or modify
3+
it under the terms of the GNU General Public License as published by
4+
the Free Software Foundation, either version 3 of the License, or
5+
(at your option) any later version.
6+
7+
This program is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
GNU General Public License for more details.
11+
12+
You should have received a copy of the GNU General Public License
13+
along with this program. If not, see <http://www.gnu.org/licenses/>.
14+
*/
15+
16+
#include "AP_Periph.h"
17+
18+
#if AP_PERIPH_ACTUATOR_TELEM_ENABLED
19+
20+
#include <dronecan_msgs.h>
21+
22+
extern const AP_HAL::HAL &hal;
23+
24+
#ifndef AP_PERIPH_ACTUATOR_TELEM_RATE_DEFAULT
25+
#define AP_PERIPH_ACTUATOR_TELEM_RATE_DEFAULT 10
26+
#endif
27+
28+
#ifndef AP_PERIPH_ACTUATOR_TELEM_NUM_CHANNELS_DEFAULT
29+
#define AP_PERIPH_ACTUATOR_TELEM_NUM_CHANNELS_DEFAULT 0
30+
#endif
31+
32+
#ifndef AP_PERIPH_ACTUATOR_TELEM_CURR_PIN_DEFAULT
33+
#define AP_PERIPH_ACTUATOR_TELEM_CURR_PIN_DEFAULT -1
34+
#endif
35+
36+
#ifndef AP_PERIPH_ACTUATOR_TELEM_CURR_AMP_OFFSET_DEFAULT
37+
#define AP_PERIPH_ACTUATOR_TELEM_CURR_AMP_OFFSET_DEFAULT 0.0f
38+
#endif
39+
40+
#ifndef AP_PERIPH_ACTUATOR_TELEM_CURR_AMP_PERVLT_DEFAULT
41+
#define AP_PERIPH_ACTUATOR_TELEM_CURR_AMP_PERVLT_DEFAULT 10
42+
#endif
43+
44+
#ifndef AP_PERIPH_ACTUATOR_TELEM_CURR_MAX_DEFAULT
45+
#define AP_PERIPH_ACTUATOR_TELEM_CURR_MAX_DEFAULT 2.5f
46+
#endif
47+
48+
const AP_Param::GroupInfo ActuatorTelem::var_info[] = {
49+
// @Param: _TELEM_RATE
50+
// @DisplayName: Actuator Telemetry rate
51+
// @Description: Actuator Telemetry update rate in Hz. Set to 0 to disable.
52+
// @Units: Hz
53+
// @Range: 0 100
54+
// @User: Standard
55+
AP_GROUPINFO("_TELEM_RATE", 1, ActuatorTelem, rate, AP_PERIPH_ACTUATOR_TELEM_RATE_DEFAULT),
56+
57+
// @Param: _NUM_CHANS
58+
// @DisplayName: Number of actuator channels
59+
// @Description: Number of actuator channels to monitor for telemetry.
60+
// @Range: 0 4
61+
// @User: Standard
62+
AP_GROUPINFO("_NUM_CHANS", 2, ActuatorTelem, num_chans, AP_PERIPH_ACTUATOR_TELEM_NUM_CHANNELS_DEFAULT),
63+
64+
// @Param: _CURR_PIN1
65+
// @DisplayName: Current sensing pin 1
66+
// @Description: Analog input pin number for current sensing on channel 1. Set to -1 to disable.
67+
// @Values: -1:Disabled
68+
// @Range: -1 127
69+
// @User: Standard
70+
// @RebootRequired: True
71+
AP_GROUPINFO("_CURR_PIN1", 3, ActuatorTelem, curr_pin1, AP_PERIPH_ACTUATOR_TELEM_CURR_PIN_DEFAULT),
72+
73+
// @Param: _AMP_OFFSET
74+
// @DisplayName: Current sensor offset
75+
// @Description: Voltage offset at zero current on the current sensor.
76+
// @Units: V
77+
// @User: Standard
78+
AP_GROUPINFO("AMP_OFFSET", 4, ActuatorTelem, curr_amp_offset, AP_PERIPH_ACTUATOR_TELEM_CURR_AMP_OFFSET_DEFAULT),
79+
80+
// @Param: _AMP_PERVLT
81+
// @DisplayName: Amps per volt
82+
// @Description: Current sensor scale factor.
83+
// @Units: A/V
84+
// @User: Standard
85+
AP_GROUPINFO("AMP_PERVLT", 5, ActuatorTelem, curr_amp_per_volt, AP_PERIPH_ACTUATOR_TELEM_CURR_AMP_PERVLT_DEFAULT),
86+
87+
// @Param: _CURR_MAX
88+
// @DisplayName: Maximum current
89+
// @Description: Maximum expected current for this channel.
90+
// @Units: A
91+
// @User: Standard
92+
AP_GROUPINFO("CURR_MAX", 6, ActuatorTelem, curr_max, AP_PERIPH_ACTUATOR_TELEM_CURR_MAX_DEFAULT),
93+
94+
AP_GROUPEND
95+
};
96+
97+
ActuatorTelem::ActuatorTelem(void)
98+
{
99+
AP_Param::setup_object_defaults(this, var_info);
100+
for (uint8_t i = 0; i < HAL_ACTUATOR_TELEM_CURR_MAX_CHANNELS; i++) {
101+
analog_sources[i] = nullptr;
102+
}
103+
}
104+
105+
void ActuatorTelem::init(void)
106+
{
107+
const int8_t curr_pin1_val = curr_pin1.get();
108+
const int8_t num_chans_val = num_chans.get();
109+
110+
if (curr_pin1_val >= 0 && num_chans_val > 0) {
111+
for (uint8_t i = 0; i < MIN(HAL_ACTUATOR_TELEM_CURR_MAX_CHANNELS, num_chans_val); i++) {
112+
const int8_t pin = curr_pin1_val + i;
113+
if (pin >= 0) {
114+
analog_sources[i] = hal.analogin->channel(pin);
115+
}
116+
}
117+
}
118+
}
119+
120+
void ActuatorTelem::send_telemetry(uint8_t channel_index, uint8_t actuator_id)
121+
{
122+
// Check if this channel is enabled
123+
if (channel_index >= HAL_ACTUATOR_TELEM_CURR_MAX_CHANNELS) {
124+
return;
125+
}
126+
127+
AP_HAL::AnalogSource *source = analog_sources[channel_index];
128+
if (source == nullptr) {
129+
return;
130+
}
131+
// Read current from analog input
132+
float current_amp = 0;
133+
float adc_voltage = source->voltage_average();
134+
current_amp = (adc_voltage - curr_amp_offset) * curr_amp_per_volt;
135+
136+
uavcan_equipment_actuator_Status pkt {};
137+
138+
pkt.actuator_id = actuator_id;
139+
pkt.position = nanf(""); // Not available
140+
pkt.force = nanf(""); // Not available
141+
pkt.speed = nanf(""); // Not available
142+
143+
// Calculate power rating percentage from current
144+
const float max_current = curr_max;
145+
if (max_current > 0 && current_amp >= 0) {
146+
pkt.power_rating_pct = constrain_int16(current_amp / max_current * 100.0f, 0, 100);
147+
} else {
148+
pkt.power_rating_pct = UAVCAN_EQUIPMENT_ACTUATOR_STATUS_POWER_RATING_PCT_UNKNOWN;
149+
}
150+
151+
// encode and broadcast
152+
uint8_t buffer[UAVCAN_EQUIPMENT_ACTUATOR_STATUS_MAX_SIZE];
153+
uint16_t total_size = uavcan_equipment_actuator_Status_encode(&pkt, buffer, !periph.canfdout());
154+
155+
periph.canard_broadcast(UAVCAN_EQUIPMENT_ACTUATOR_STATUS_SIGNATURE,
156+
UAVCAN_EQUIPMENT_ACTUATOR_STATUS_ID,
157+
CANARD_TRANSFER_PRIORITY_LOW,
158+
&buffer[0],
159+
total_size);
160+
}
161+
162+
void ActuatorTelem::update()
163+
{
164+
// Check global telemetry rate
165+
const float telem_rate = rate.get();
166+
if (telem_rate <= 0) {
167+
return; // telemetry disabled
168+
}
169+
170+
const uint32_t now = AP_HAL::millis();
171+
if (now - last_telem_update_ms < 1000.0f / telem_rate) {
172+
return;
173+
}
174+
last_telem_update_ms = now;
175+
176+
#if HAL_PWM_COUNT > 0
177+
const int8_t num_chans_val = num_chans.get();
178+
if (num_chans_val > 0) {
179+
for (uint8_t i = 0; i < MIN(HAL_PWM_COUNT, num_chans_val); i++) {
180+
const auto *srv_channel = periph.servo_channels.srv_channel(i);
181+
if (srv_channel == nullptr) {
182+
continue;
183+
}
184+
185+
const SRV_Channel::Function function = srv_channel->get_function();
186+
// Only send for configured actuator functions
187+
if (function < SRV_Channel::k_rcin1 || function > SRV_Channel::k_rcin16) {
188+
continue;
189+
}
190+
191+
const uint8_t actuator_id = function - SRV_Channel::k_rcin1 + 1;
192+
193+
send_telemetry(i, actuator_id);
194+
}
195+
}
196+
#endif
197+
}
198+
199+
#endif // AP_PERIPH_ACTUATOR_TELEM_ENABLED

Tools/AP_Periph/actuator_telem.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#pragma once
2+
3+
#if AP_PERIPH_ACTUATOR_TELEM_ENABLED
4+
5+
#ifndef HAL_ACTUATOR_TELEM_CURR_MAX_CHANNELS
6+
#define HAL_ACTUATOR_TELEM_CURR_MAX_CHANNELS 4
7+
#endif
8+
9+
// Manager for all actuator channels
10+
class ActuatorTelem {
11+
public:
12+
friend class AP_Periph_FW;
13+
ActuatorTelem(void);
14+
15+
void init(void);
16+
void send_telemetry(uint8_t channel_index, uint8_t actuator_id);
17+
void update(void);
18+
19+
static const struct AP_Param::GroupInfo var_info[];
20+
21+
private:
22+
AP_Int16 rate;
23+
AP_Int8 num_chans;
24+
AP_Int8 curr_pin1;
25+
AP_Float curr_amp_offset;
26+
AP_Float curr_amp_per_volt;
27+
AP_Float curr_max;
28+
uint32_t last_telem_update_ms;
29+
AP_HAL::AnalogSource *analog_sources[HAL_ACTUATOR_TELEM_CURR_MAX_CHANNELS];
30+
};
31+
32+
#endif // AP_PERIPH_ACTUATOR_TELEM_ENABLED

0 commit comments

Comments
 (0)