Skip to content

Commit 1724bfc

Browse files
committed
AP_Periph:add ap periph rc out current sampling and telemary support
1 parent e285b8f commit 1724bfc

File tree

6 files changed

+277
-0
lines changed

6 files changed

+277
-0
lines changed

Tools/AP_Periph/AP_Periph.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,10 @@ void AP_Periph_FW::update()
505505
rcin_update();
506506
#endif
507507

508+
#if AP_PERIPH_ACTUATOR_TELEM_ENABLED
509+
actuator_telem.update();
510+
#endif
511+
508512
#if AP_PERIPH_BATTERY_BALANCE_ENABLED
509513
batt_balance_update();
510514
#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: ../libraries/AP_Actuator_Telem/AP_Actuator_Telem.cpp
623+
GOBJECT(actuator_telem, "ACT", AP_Actuator_Telem),
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: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
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_CURR_PIN_DEFAULT
29+
#define AP_PERIPH_ACTUATOR_TELEM_CURR_PIN_DEFAULT -1
30+
#endif
31+
32+
#ifndef AP_PERIPH_ACTUATOR_TELEM_CURR_AMP_OFFSET_DEFAULT
33+
#define AP_PERIPH_ACTUATOR_TELEM_CURR_AMP_OFFSET_DEFAULT 0.0f
34+
#endif
35+
36+
#ifndef AP_PERIPH_ACTUATOR_TELEM_CURR_AMP_PERVLT_DEFAULT
37+
#define AP_PERIPH_ACTUATOR_TELEM_CURR_AMP_PERVLT_DEFAULT 10
38+
#endif
39+
40+
#ifndef AP_PERIPH_ACTUATOR_TELEM_CURR_MAX_DEFAULT
41+
#define AP_PERIPH_ACTUATOR_TELEM_CURR_MAX_DEFAULT 2.5f
42+
#endif
43+
44+
// ActuatorChannel parameter group
45+
const AP_Param::GroupInfo ActuatorChannel::var_info[] = {
46+
// @Param: _CURR_PIN
47+
// @DisplayName: Current sensing pin
48+
// @Description: Analog input pin number for current sensing. Set to -1 to disable.
49+
// @Values: -1:Disabled
50+
// @Range: -1 15
51+
// @User: Standard
52+
// @RebootRequired: True
53+
AP_GROUPINFO("CURR_PIN", 1, ActuatorChannel, curr_pin, AP_PERIPH_ACTUATOR_TELEM_CURR_PIN_DEFAULT),
54+
55+
// @Param: _AMP_OFFSET
56+
// @DisplayName: Current sensor offset
57+
// @Description: Voltage offset at zero current on the current sensor.
58+
// @Units: V
59+
// @Range: -10 10
60+
// @User: Standard
61+
AP_GROUPINFO("AMP_OFFSET", 2, ActuatorChannel, curr_amp_offset, AP_PERIPH_ACTUATOR_TELEM_CURR_AMP_OFFSET_DEFAULT),
62+
63+
// @Param: _AMP_PERVLT
64+
// @DisplayName: Amps per volt
65+
// @Description: Current sensor scale factor.
66+
// @Units: A/V
67+
// @Range: 0 100
68+
// @User: Standard
69+
AP_GROUPINFO("AMP_PERVLT", 3, ActuatorChannel, curr_amp_per_volt, AP_PERIPH_ACTUATOR_TELEM_CURR_AMP_PERVLT_DEFAULT),
70+
71+
// @Param: _CURR_MAX
72+
// @DisplayName: Maximum current
73+
// @Description: Maximum expected current for this channel.
74+
// @Units: A
75+
// @Range: 0 100
76+
// @User: Standard
77+
AP_GROUPINFO("CURR_MAX", 4, ActuatorChannel, curr_max, AP_PERIPH_ACTUATOR_TELEM_CURR_MAX_DEFAULT),
78+
79+
AP_GROUPEND
80+
};
81+
82+
const AP_Param::GroupInfo ActuatorTelem::var_info[] = {
83+
// @Param: _RATE
84+
// @DisplayName: Actuator Telemetry rate
85+
// @Description: Actuator Telemetry update rate in Hz. Set to 0 to disable.
86+
// @Units: Hz
87+
// @Range: 0 100
88+
// @User: Standard
89+
AP_GROUPINFO("_TELEM_RATE", 1, ActuatorTelem, rate, AP_PERIPH_ACTUATOR_TELEM_RATE_DEFAULT),
90+
91+
#if (HAL_ACTUATOR_TELEM_CHANNELS >= 1)
92+
// @Group: 1_
93+
// @Path: actuator_telem.cpp
94+
AP_SUBGROUPINFO(channels[0], "1_", 2, ActuatorTelem, ActuatorChannel),
95+
#endif
96+
97+
#if (HAL_ACTUATOR_TELEM_CHANNELS >= 2)
98+
// @Group: 2_
99+
// @Path: actuator_telem.cpp
100+
AP_SUBGROUPINFO(channels[1], "2_", 3, ActuatorTelem, ActuatorChannel),
101+
#endif
102+
103+
#if (HAL_ACTUATOR_TELEM_CHANNELS >= 3)
104+
// @Group: 3_
105+
// @Path: actuator_telem.cpp
106+
AP_SUBGROUPINFO(channels[2], "3_", 4, ActuatorTelem, ActuatorChannel),
107+
#endif
108+
109+
#if (HAL_ACTUATOR_TELEM_CHANNELS >= 4)
110+
// @Group: 4_
111+
// @Path: actuator_telem.cpp
112+
AP_SUBGROUPINFO(channels[3], "4_", 5, ActuatorTelem, ActuatorChannel),
113+
#endif
114+
115+
AP_GROUPEND
116+
};
117+
118+
ActuatorChannel::ActuatorChannel(void) :
119+
analog_source(nullptr)
120+
{
121+
}
122+
123+
void ActuatorChannel::init(void)
124+
{
125+
if (curr_pin >= 0 && analog_source == nullptr) {
126+
analog_source = hal.analogin->channel(curr_pin);
127+
}
128+
}
129+
130+
void ActuatorChannel::send_telemetry(uint8_t actuator_id)
131+
{
132+
// Check if this channel is enabled
133+
if (curr_pin < 0 || analog_source == nullptr) {
134+
return;
135+
}
136+
137+
// Read current from analog input
138+
float current_amp = 0;
139+
float adc_voltage = analog_source->voltage_average();
140+
current_amp = (adc_voltage - curr_amp_offset) * curr_amp_per_volt;
141+
142+
uavcan_equipment_actuator_Status pkt {};
143+
144+
pkt.actuator_id = actuator_id;
145+
pkt.position = nanf(""); // Not available
146+
pkt.force = nanf(""); // Not available
147+
pkt.speed = nanf(""); // Not available
148+
149+
// Calculate power rating percentage from current
150+
const float max_current = curr_max;
151+
if (max_current > 0 && current_amp >= 0) {
152+
pkt.power_rating_pct = constrain_int16(current_amp / max_current * 100.0f, 0, 100);
153+
} else {
154+
pkt.power_rating_pct = UAVCAN_EQUIPMENT_ACTUATOR_STATUS_POWER_RATING_PCT_UNKNOWN;
155+
}
156+
157+
// encode and broadcast
158+
uint8_t buffer[UAVCAN_EQUIPMENT_ACTUATOR_STATUS_MAX_SIZE];
159+
uint16_t total_size = uavcan_equipment_actuator_Status_encode(&pkt, buffer, !periph.canfdout());
160+
161+
periph.canard_broadcast(UAVCAN_EQUIPMENT_ACTUATOR_STATUS_SIGNATURE,
162+
UAVCAN_EQUIPMENT_ACTUATOR_STATUS_ID,
163+
CANARD_TRANSFER_PRIORITY_LOW,
164+
&buffer[0],
165+
total_size);
166+
}
167+
168+
ActuatorTelem::ActuatorTelem(void)
169+
{
170+
AP_Param::setup_object_defaults(this, var_info);
171+
}
172+
173+
void ActuatorTelem::update()
174+
{
175+
// Check global telemetry rate
176+
const float telem_rate = rate.get();
177+
if (telem_rate <= 0) {
178+
return; // telemetry disabled
179+
}
180+
181+
const uint32_t now = AP_HAL::millis();
182+
if (now - last_telem_update_ms < 1000.0f / telem_rate) {
183+
return;
184+
}
185+
last_telem_update_ms = now;
186+
187+
#if HAL_PWM_COUNT > 0
188+
// Check all channels - each manages its own timing to space out broadcasts
189+
for (uint8_t i = 0; i < HAL_PWM_COUNT; i++) {
190+
const auto *srv_channel = periph.servo_channels.srv_channel(i);
191+
if (srv_channel == nullptr) {
192+
continue;
193+
}
194+
195+
const SRV_Channel::Function function = srv_channel->get_function();
196+
// Only send for configured actuator functions
197+
if (function < SRV_Channel::k_rcin1 || function > SRV_Channel::k_rcin16) {
198+
continue;
199+
}
200+
201+
const uint8_t actuator_id = function - SRV_Channel::k_rcin1 + 1;
202+
203+
// Initialize channel if needed
204+
channels[i].init();
205+
206+
// Each channel checks its own timing - broadcasts are staggered
207+
channels[i].send_telemetry(actuator_id);
208+
}
209+
#endif
210+
}
211+
212+
#endif // AP_PERIPH_ACTUATOR_TELEM_ENABLED

Tools/AP_Periph/actuator_telem.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma once
2+
3+
#if AP_PERIPH_ACTUATOR_TELEM_ENABLED
4+
5+
#ifndef HAL_ACTUATOR_TELEM_CHANNELS
6+
#define HAL_ACTUATOR_TELEM_CHANNELS 0
7+
#endif
8+
9+
// Individual actuator channel with current sensing
10+
class ActuatorChannel {
11+
public:
12+
friend class ActuatorTelem;
13+
14+
ActuatorChannel(void);
15+
16+
static const struct AP_Param::GroupInfo var_info[];
17+
18+
void init(void);
19+
void send_telemetry(uint8_t actuator_id);
20+
21+
private:
22+
AP_Int8 curr_pin;
23+
AP_Float curr_amp_offset;
24+
AP_Float curr_amp_per_volt;
25+
AP_Float curr_max;
26+
27+
AP_HAL::AnalogSource *analog_source;
28+
};
29+
30+
// Manager for all actuator channels
31+
class ActuatorTelem {
32+
public:
33+
friend class AP_Periph_FW;
34+
ActuatorTelem(void);
35+
36+
void update(void);
37+
38+
static const struct AP_Param::GroupInfo var_info[];
39+
40+
private:
41+
AP_Float rate;
42+
uint32_t last_telem_update_ms;
43+
44+
ActuatorChannel channels[HAL_ACTUATOR_TELEM_CHANNELS];
45+
};
46+
47+
typedef ActuatorTelem AP_Actuator_Telem;
48+
49+
#endif // AP_PERIPH_ACTUATOR_TELEM_ENABLED

0 commit comments

Comments
 (0)