@@ -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