1+ #include < thread>
2+ #include < iostream>
3+ #include < exception>
4+ #include < linux/can.h>
5+ #include < stdexcept>
6+ #include < string>
7+
8+ #include " meta_hardware/can_driver/can_driver.hpp"
9+ #include " meta_hardware/can_driver/can_exceptions.hpp"
10+ #include " super_capacitor/super_capacitor_base.h"
11+ #include " super_capacitor/pacific_spirit_capacitor_driver.h"
12+
13+ namespace super_capacitor {
14+ PacificSpiritCapacitorDriver::PacificSpiritCapacitorDriver ()
15+ : super_capacitor::SuperCapacitorBase(){}
16+
17+ void PacificSpiritCapacitorDriver::init (std::string can_interface){
18+ can_filters_.push_back ({.can_id = 0x2c8 , .can_mask = CAN_EFF_MASK});
19+ // Initialize CAN driver
20+ can_driver_ = std::make_unique<meta_hardware::CanDriver>(can_interface, false , can_filters_);
21+
22+ // Initialize RX thread
23+ rx_thread_ =
24+ std::make_unique<std::jthread>([this ](std::stop_token s) { rx_loop (s); });
25+ }
26+
27+ void PacificSpiritCapacitorDriver::set_target_power (double power) {
28+ target_power_ = power;
29+ }
30+
31+ void PacificSpiritCapacitorDriver::set_referee_power (double power) {
32+ referee_power_ = power;
33+ }
34+
35+ std::unordered_map<std::string, double > PacificSpiritCapacitorDriver::get_state () {
36+ return {
37+ {" max_discharge_power" , max_discharge_power_},
38+ {" base_power" , base_power_},
39+ {" cap_energy_percentage" , cap_energy_percentage_},
40+ {" cap_state" , cap_state_}
41+ };
42+ }
43+
44+ std::string PacificSpiritCapacitorDriver::get_device_name () {
45+ return " Xidi Capacitor" ;
46+ }
47+
48+ void PacificSpiritCapacitorDriver::rx_loop (std::stop_token stop_token) {
49+ while (!stop_token.stop_requested ()) {
50+ try {
51+ can_frame can_msg = can_driver_->read (2000 );
52+
53+ max_discharge_power_ = static_cast <double >(static_cast <uint16_t >(static_cast <uint16_t >(can_msg.data [0 ]) |
54+ (static_cast <uint16_t >(can_msg.data [1 ]) << 8 )) / 100.0 );
55+ base_power_ = static_cast <double >(static_cast <uint16_t >(static_cast <uint16_t >(can_msg.data [2 ]) |
56+ (static_cast <uint16_t >(can_msg.data [3 ]) << 8 )) / 100.0 );
57+ cap_energy_percentage_ = static_cast <double >(static_cast <uint16_t >(static_cast <uint16_t >(can_msg.data [4 ]) |
58+ (static_cast <uint16_t >(can_msg.data [5 ]) << 8 )) / 100.0 );
59+ cap_state_ = static_cast <double >(static_cast <uint16_t >(static_cast <uint16_t >(can_msg.data [6 ]) |
60+ (static_cast <uint16_t >(can_msg.data [7 ]) << 8 )) / 100.0 );
61+ } catch (const meta_hardware::CanIOException &e) {
62+ std::cerr << " Error reading super capacitor CAN message: " << e.what () << std::endl;
63+ }
64+ }
65+
66+ }
67+
68+ void PacificSpiritCapacitorDriver::tx (){
69+ can_frame tx_frame{.can_id = 0x2c7 , .len = 8 , .data = {0 }};
70+ tx_frame.data [0 ] = static_cast <uint8_t >(static_cast <uint32_t >(target_power_ * 100.0 ) & 0xFF );
71+ tx_frame.data [1 ] = static_cast <uint8_t >(static_cast <uint32_t >(target_power_ * 100.0 ) >> 8 );
72+ tx_frame.data [2 ] = static_cast <uint8_t >(static_cast <uint32_t >(referee_power_ * 100.0 ) & 0xFF );
73+ tx_frame.data [3 ] = static_cast <uint8_t >(static_cast <uint32_t >(referee_power_ * 100.0 ) >> 8 );
74+ tx_frame.data [4 ] = 0x12 ;
75+ tx_frame.data [5 ] = 0x20 ;
76+ tx_frame.data [6 ] = 0x12 ;
77+ tx_frame.data [7 ] = 0x07 ;
78+ try {
79+ can_driver_->write (tx_frame);
80+ } catch (meta_hardware::CanIOException &e) {
81+ std::cerr << " Error writing CAN message: " << e.what () << std::endl;
82+ }
83+ }
84+
85+ PacificSpiritCapacitorDriver::~PacificSpiritCapacitorDriver () {
86+ if (rx_thread_ && rx_thread_->joinable ()) {
87+ rx_thread_->request_stop (); // Gracefully stop the thread
88+ rx_thread_->join ();
89+ }
90+ }
91+
92+ }
93+
94+ // #include <pluginlib/class_list_macros.hpp>
95+ // PLUGINLIB_EXPORT_CLASS(super_capacitor::PacificSpiritCapacitorDriver, super_capacitor::SuperCapacitorBase)
0 commit comments