Skip to content

Commit 4fd5996

Browse files
avatarsdAvatarSD
authored andcommitted
Feature: Combined batteries data info
1 parent 1625684 commit 4fd5996

File tree

2 files changed

+89
-4
lines changed

2 files changed

+89
-4
lines changed

psdk_wrapper/include/psdk_wrapper/modules/telemetry.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,15 @@ class TelemetryModule : public rclcpp_lifecycle::LifecycleNode
11131113

11141114
mutable std::shared_mutex current_state_mutex_;
11151115
mutable std::shared_mutex global_ptr_mutex_;
1116+
1117+
/* Battery info merging utility */
1118+
void publish_combined_battery_state();
1119+
std::atomic<bool> battery_info_subscription_failed_{false};
1120+
std::atomic<bool> has_battery1_info_{false};
1121+
std::atomic<bool> has_battery2_info_{false};
1122+
psdk_interfaces::msg::SingleBatteryInfo last_battery1_info_;
1123+
psdk_interfaces::msg::SingleBatteryInfo last_battery2_info_;
1124+
std::mutex battery_info_mutex_;
11161125
};
11171126

11181127
extern std::shared_ptr<TelemetryModule> global_telemetry_ptr_;

psdk_wrapper/src/modules/telemetry.cpp

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,11 +1806,26 @@ TelemetryModule::single_battery_index1_callback(
18061806
single_battery_info->batteryState.batteryCommunicationAbnormal;
18071807
single_battery_info_msg.is_embed =
18081808
single_battery_info->batteryState.isBatteryEmbed;
1809-
if (single_battery_index1_pub_ && single_battery_index1_pub_->is_activated())
1810-
{
1809+
1810+
if (single_battery_index1_pub_ && single_battery_index1_pub_->is_activated()) {
18111811
single_battery_index1_pub_->publish(single_battery_info_msg);
1812+
} else {
1813+
RCLCPP_ERROR(this->get_logger(), "Failed to publish single_battery_index1 data");
1814+
}
1815+
1816+
// Store the latest battery 1 info with mutex protection
1817+
{
1818+
std::lock_guard<std::mutex> lock(battery_info_mutex_);
1819+
last_battery1_info_ = single_battery_info_msg;
18121820
}
1821+
has_battery1_info_.store(true, std::memory_order_relaxed);
18131822

1823+
// Publish combined state if both batteries have data and battery info subscription failed
1824+
if (has_battery1_info_.load(std::memory_order_relaxed) &&
1825+
has_battery2_info_.load(std::memory_order_relaxed) &&
1826+
battery_info_subscription_failed_.load(std::memory_order_relaxed)) {
1827+
publish_combined_battery_state();
1828+
}
18141829
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
18151830
}
18161831

@@ -1857,9 +1872,25 @@ TelemetryModule::single_battery_index2_callback(
18571872
single_battery_info->batteryState.batteryCommunicationAbnormal;
18581873
single_battery_info_msg.is_embed =
18591874
single_battery_info->batteryState.isBatteryEmbed;
1860-
if (single_battery_index2_pub_ && single_battery_index2_pub_->is_activated())
1861-
{
1875+
1876+
if (single_battery_index2_pub_ && single_battery_index2_pub_->is_activated()) {
18621877
single_battery_index2_pub_->publish(single_battery_info_msg);
1878+
} else {
1879+
RCLCPP_ERROR(this->get_logger(), "Failed to publish single_battery_index2 data");
1880+
}
1881+
1882+
// Store the latest battery 2 info with mutex protection
1883+
{
1884+
std::lock_guard<std::mutex> lock(battery_info_mutex_);
1885+
last_battery2_info_ = single_battery_info_msg;
1886+
}
1887+
has_battery2_info_.store(true, std::memory_order_relaxed);
1888+
1889+
// Publish combined state if both batteries have data and battery info subscription failed
1890+
if (has_battery1_info_.load(std::memory_order_relaxed) &&
1891+
has_battery2_info_.load(std::memory_order_relaxed) &&
1892+
battery_info_subscription_failed_.load(std::memory_order_relaxed)) {
1893+
publish_combined_battery_state();
18631894
}
18641895
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
18651896
}
@@ -2354,6 +2385,9 @@ TelemetryModule::subscribe_psdk_topics()
23542385
"Could not subscribe successfully to topic "
23552386
"DJI_FC_SUBSCRIPTION_TOPIC_BATTERY_INFO, error %ld",
23562387
return_code);
2388+
battery_info_subscription_failed_.store(true, std::memory_order_relaxed);
2389+
} else {
2390+
battery_info_subscription_failed_.store(false, std::memory_order_relaxed);
23572391
}
23582392
return_code = DjiFcSubscription_SubscribeTopic(
23592393
DJI_FC_SUBSCRIPTION_TOPIC_BATTERY_SINGLE_INFO_INDEX1,
@@ -2724,4 +2758,46 @@ TelemetryModule::initialize_aircraft_base_info()
27242758
aircraft_base_.mountPosition = DJI_MOUNT_POSITION_UNKNOWN;
27252759
}
27262760

2761+
void
2762+
TelemetryModule::publish_combined_battery_state() {
2763+
sensor_msgs::msg::BatteryState combined_msg;
2764+
auto max_time = [](
2765+
const builtin_interfaces::msg::Time& t1,
2766+
const builtin_interfaces::msg::Time& t2) -> builtin_interfaces::msg::Time {
2767+
if (t1.sec > t2.sec) {
2768+
return t1;
2769+
} else if (t1.sec < t2.sec) {
2770+
return t2;
2771+
} else {
2772+
// Seconds are equal, compare nanoseconds
2773+
return t1.nanosec >= t2.nanosec ? t1 : t2;
2774+
}
2775+
};
2776+
{
2777+
std::lock_guard<std::mutex> lock(battery_info_mutex_);
2778+
combined_msg.header.stamp = max_time(last_battery1_info_.header.stamp, last_battery2_info_.header.stamp);
2779+
combined_msg.voltage = (last_battery1_info_.voltage + last_battery2_info_.voltage) / 2;
2780+
combined_msg.current = last_battery1_info_.current + last_battery2_info_.current;
2781+
combined_msg.capacity = last_battery1_info_.capacity_remain + last_battery2_info_.capacity_remain;
2782+
combined_msg.design_capacity = last_battery1_info_.full_capacity + last_battery2_info_.full_capacity;
2783+
combined_msg.percentage = (last_battery1_info_.capacity_percentage + last_battery2_info_.capacity_percentage) / 2;
2784+
combined_msg.temperature = std::max(last_battery1_info_.temperature, last_battery2_info_.temperature);
2785+
}
2786+
// Detailed debug log
2787+
RCLCPP_DEBUG(this->get_logger(),
2788+
"Combined battery data: voltage=%.2fV, current=%.2fA, capacity=%.2fAh, "
2789+
"percentage=%.2f, temperature=%.1fC",
2790+
combined_msg.voltage,
2791+
combined_msg.current,
2792+
combined_msg.capacity,
2793+
combined_msg.percentage,
2794+
combined_msg.temperature);
2795+
2796+
if (battery_pub_ && battery_pub_->is_activated()) {
2797+
battery_pub_->publish(combined_msg);
2798+
} else {
2799+
RCLCPP_ERROR(this->get_logger(), "Failed to publish combined battery state: Publisher not available");
2800+
}
2801+
}
2802+
27272803
} // namespace psdk_ros2

0 commit comments

Comments
 (0)