|
@@ -6,24 +6,27 @@
|
|
|
using namespace std::chrono_literals;
|
|
using namespace std::chrono_literals;
|
|
|
using std::placeholders::_1;
|
|
using std::placeholders::_1;
|
|
|
|
|
|
|
|
-WorkflowManager::WorkflowManager(rclcpp::Node* node)
|
|
|
|
|
- : node_(node)
|
|
|
|
|
- , current_state_(WheelchairState::READY)
|
|
|
|
|
|
|
+WorkflowManager::WorkflowManager(rclcpp::Node *node)
|
|
|
|
|
+ : node_(node), current_state_(WheelchairState::READY)
|
|
|
{
|
|
{
|
|
|
// 初始化状态转移表
|
|
// 初始化状态转移表
|
|
|
initializeTransitionTable();
|
|
initializeTransitionTable();
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 创建状态发布者
|
|
// 创建状态发布者
|
|
|
state_publisher_ = node_->create_publisher<std_msgs::msg::String>(
|
|
state_publisher_ = node_->create_publisher<std_msgs::msg::String>(
|
|
|
"wheelchair/state", 10);
|
|
"wheelchair/state", 10);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 创建回充超时报告发布者
|
|
|
|
|
+ recharge_timeout_publisher_ = node_->create_publisher<std_msgs::msg::String>(
|
|
|
|
|
+ "wheelchair/recharge_timeout", 10);
|
|
|
|
|
+
|
|
|
RCLCPP_INFO(node_->get_logger(), "工作流管理器已初始化");
|
|
RCLCPP_INFO(node_->get_logger(), "工作流管理器已初始化");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::initializeTransitionTable()
|
|
void WorkflowManager::initializeTransitionTable()
|
|
|
{
|
|
{
|
|
|
transition_table_.clear();
|
|
transition_table_.clear();
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 1. ipad&phone界面启动: 就绪中✅, 其他❌
|
|
// 1. ipad&phone界面启动: 就绪中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> ipad_start_perms = {
|
|
std::map<WheelchairState, bool> ipad_start_perms = {
|
|
|
{WheelchairState::READY, true},
|
|
{WheelchairState::READY, true},
|
|
@@ -31,7 +34,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, false},
|
|
{WheelchairState::SEARCHING, false},
|
|
|
{WheelchairState::CHARGING, false}};
|
|
{WheelchairState::CHARGING, false}};
|
|
|
transition_table_["ipad_phone_interface_start"] = ipad_start_perms;
|
|
transition_table_["ipad_phone_interface_start"] = ipad_start_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 2. iPad&phone界面取消: 所有状态✅
|
|
// 2. iPad&phone界面取消: 所有状态✅
|
|
|
std::map<WheelchairState, bool> ipad_cancel_perms = {
|
|
std::map<WheelchairState, bool> ipad_cancel_perms = {
|
|
|
{WheelchairState::READY, true},
|
|
{WheelchairState::READY, true},
|
|
@@ -39,7 +42,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, true},
|
|
{WheelchairState::SEARCHING, true},
|
|
|
{WheelchairState::CHARGING, true}};
|
|
{WheelchairState::CHARGING, true}};
|
|
|
transition_table_["ipad_phone_interface_cancel"] = ipad_cancel_perms;
|
|
transition_table_["ipad_phone_interface_cancel"] = ipad_cancel_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 3. 蓝牙断开: 就绪中❌, 其他✅
|
|
// 3. 蓝牙断开: 就绪中❌, 其他✅
|
|
|
std::map<WheelchairState, bool> bluetooth_disconnect_perms = {
|
|
std::map<WheelchairState, bool> bluetooth_disconnect_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
@@ -47,7 +50,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, true},
|
|
{WheelchairState::SEARCHING, true},
|
|
|
{WheelchairState::CHARGING, true}};
|
|
{WheelchairState::CHARGING, true}};
|
|
|
transition_table_["bluetooth_disconnected"] = bluetooth_disconnect_perms;
|
|
transition_table_["bluetooth_disconnected"] = bluetooth_disconnect_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 4. 蓝牙已连接: 就绪中✅, 其他❌
|
|
// 4. 蓝牙已连接: 就绪中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> bluetooth_connect_perms = {
|
|
std::map<WheelchairState, bool> bluetooth_connect_perms = {
|
|
|
{WheelchairState::READY, true},
|
|
{WheelchairState::READY, true},
|
|
@@ -55,7 +58,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, false},
|
|
{WheelchairState::SEARCHING, false},
|
|
|
{WheelchairState::CHARGING, false}};
|
|
{WheelchairState::CHARGING, false}};
|
|
|
transition_table_["bluetooth_connected"] = bluetooth_connect_perms;
|
|
transition_table_["bluetooth_connected"] = bluetooth_connect_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 5. 基站断电: 就绪中❌, 其他✅
|
|
// 5. 基站断电: 就绪中❌, 其他✅
|
|
|
std::map<WheelchairState, bool> base_power_off_perms = {
|
|
std::map<WheelchairState, bool> base_power_off_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
@@ -63,7 +66,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, true},
|
|
{WheelchairState::SEARCHING, true},
|
|
|
{WheelchairState::CHARGING, true}};
|
|
{WheelchairState::CHARGING, true}};
|
|
|
transition_table_["base_station_power_off"] = base_power_off_perms;
|
|
transition_table_["base_station_power_off"] = base_power_off_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 6. 低电量警告: 就绪中✅, 其他❌
|
|
// 6. 低电量警告: 就绪中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> low_battery_perms = {
|
|
std::map<WheelchairState, bool> low_battery_perms = {
|
|
|
{WheelchairState::READY, true},
|
|
{WheelchairState::READY, true},
|
|
@@ -71,7 +74,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, false},
|
|
{WheelchairState::SEARCHING, false},
|
|
|
{WheelchairState::CHARGING, false}};
|
|
{WheelchairState::CHARGING, false}};
|
|
|
transition_table_["low_battery_warning"] = low_battery_perms;
|
|
transition_table_["low_battery_warning"] = low_battery_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 7. 锁车: 就绪中✅, 其他❌
|
|
// 7. 锁车: 就绪中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> lock_vehicle_perms = {
|
|
std::map<WheelchairState, bool> lock_vehicle_perms = {
|
|
|
{WheelchairState::READY, true},
|
|
{WheelchairState::READY, true},
|
|
@@ -79,7 +82,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, false},
|
|
{WheelchairState::SEARCHING, false},
|
|
|
{WheelchairState::CHARGING, false}};
|
|
{WheelchairState::CHARGING, false}};
|
|
|
transition_table_["lock_vehicle"] = lock_vehicle_perms;
|
|
transition_table_["lock_vehicle"] = lock_vehicle_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 8. 解锁: 行走中✅, 其他❌
|
|
// 8. 解锁: 行走中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> unlock_vehicle_perms = {
|
|
std::map<WheelchairState, bool> unlock_vehicle_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
@@ -87,7 +90,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, false},
|
|
{WheelchairState::SEARCHING, false},
|
|
|
{WheelchairState::CHARGING, false}};
|
|
{WheelchairState::CHARGING, false}};
|
|
|
transition_table_["unlock_vehicle"] = unlock_vehicle_perms;
|
|
transition_table_["unlock_vehicle"] = unlock_vehicle_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 9. 摇杆后拉: 搜索中✅, 其他❌
|
|
// 9. 摇杆后拉: 搜索中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> joystick_pull_perms = {
|
|
std::map<WheelchairState, bool> joystick_pull_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
@@ -95,7 +98,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, true},
|
|
{WheelchairState::SEARCHING, true},
|
|
|
{WheelchairState::CHARGING, false}};
|
|
{WheelchairState::CHARGING, false}};
|
|
|
transition_table_["joystick_pull_back"] = joystick_pull_perms;
|
|
transition_table_["joystick_pull_back"] = joystick_pull_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 10. 摇杆停止: 行走中✅, 搜索中✅, 其他❌
|
|
// 10. 摇杆停止: 行走中✅, 搜索中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> joystick_stop_perms = {
|
|
std::map<WheelchairState, bool> joystick_stop_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
@@ -103,7 +106,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, true},
|
|
{WheelchairState::SEARCHING, true},
|
|
|
{WheelchairState::CHARGING, false}};
|
|
{WheelchairState::CHARGING, false}};
|
|
|
transition_table_["joystick_stop"] = joystick_stop_perms;
|
|
transition_table_["joystick_stop"] = joystick_stop_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 11. 推行启动: 充电中✅, 其他❌
|
|
// 11. 推行启动: 充电中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> push_start_perms = {
|
|
std::map<WheelchairState, bool> push_start_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
@@ -111,7 +114,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, false},
|
|
{WheelchairState::SEARCHING, false},
|
|
|
{WheelchairState::CHARGING, true}};
|
|
{WheelchairState::CHARGING, true}};
|
|
|
transition_table_["push_start"] = push_start_perms;
|
|
transition_table_["push_start"] = push_start_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 12. 推行关闭: 行走中✅, 搜索中✅, 其他❌
|
|
// 12. 推行关闭: 行走中✅, 搜索中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> push_stop_perms = {
|
|
std::map<WheelchairState, bool> push_stop_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
@@ -119,7 +122,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, true},
|
|
{WheelchairState::SEARCHING, true},
|
|
|
{WheelchairState::CHARGING, false}};
|
|
{WheelchairState::CHARGING, false}};
|
|
|
transition_table_["push_stop"] = push_stop_perms;
|
|
transition_table_["push_stop"] = push_stop_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 13. 电池-开始充电: 搜索中✅, 充电中✅, 其他❌
|
|
// 13. 电池-开始充电: 搜索中✅, 充电中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> battery_start_charging_perms = {
|
|
std::map<WheelchairState, bool> battery_start_charging_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
@@ -127,7 +130,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, true},
|
|
{WheelchairState::SEARCHING, true},
|
|
|
{WheelchairState::CHARGING, true}};
|
|
{WheelchairState::CHARGING, true}};
|
|
|
transition_table_["battery_start_charging"] = battery_start_charging_perms;
|
|
transition_table_["battery_start_charging"] = battery_start_charging_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 14. 电池-断开充电: 充电中✅, 其他❌
|
|
// 14. 电池-断开充电: 充电中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> battery_stop_charging_perms = {
|
|
std::map<WheelchairState, bool> battery_stop_charging_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
@@ -135,7 +138,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, false},
|
|
{WheelchairState::SEARCHING, false},
|
|
|
{WheelchairState::CHARGING, true}};
|
|
{WheelchairState::CHARGING, true}};
|
|
|
transition_table_["battery_stop_charging"] = battery_stop_charging_perms;
|
|
transition_table_["battery_stop_charging"] = battery_stop_charging_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 15. 电池-电量满: 充电中✅, 其他❌
|
|
// 15. 电池-电量满: 充电中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> battery_full_perms = {
|
|
std::map<WheelchairState, bool> battery_full_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
@@ -143,7 +146,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, false},
|
|
{WheelchairState::SEARCHING, false},
|
|
|
{WheelchairState::CHARGING, true}};
|
|
{WheelchairState::CHARGING, true}};
|
|
|
transition_table_["battery_full"] = battery_full_perms;
|
|
transition_table_["battery_full"] = battery_full_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 16. 错误码处理: 所有状态✅
|
|
// 16. 错误码处理: 所有状态✅
|
|
|
std::map<WheelchairState, bool> error_code_perms = {
|
|
std::map<WheelchairState, bool> error_code_perms = {
|
|
|
{WheelchairState::READY, true},
|
|
{WheelchairState::READY, true},
|
|
@@ -151,7 +154,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, true},
|
|
{WheelchairState::SEARCHING, true},
|
|
|
{WheelchairState::CHARGING, true}};
|
|
{WheelchairState::CHARGING, true}};
|
|
|
transition_table_["error_code_handling"] = error_code_perms;
|
|
transition_table_["error_code_handling"] = error_code_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 17. 基站检测丢失: 行走中✅, 其他❌
|
|
// 17. 基站检测丢失: 行走中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> base_station_lost_perms = {
|
|
std::map<WheelchairState, bool> base_station_lost_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
@@ -159,7 +162,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, false},
|
|
{WheelchairState::SEARCHING, false},
|
|
|
{WheelchairState::CHARGING, false}};
|
|
{WheelchairState::CHARGING, false}};
|
|
|
transition_table_["base_station_lost"] = base_station_lost_perms;
|
|
transition_table_["base_station_lost"] = base_station_lost_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 18. 搜索30s超时: 搜索中✅, 其他❌
|
|
// 18. 搜索30s超时: 搜索中✅, 其他❌
|
|
|
std::map<WheelchairState, bool> search_timeout_perms = {
|
|
std::map<WheelchairState, bool> search_timeout_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
@@ -167,7 +170,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
{WheelchairState::SEARCHING, true},
|
|
{WheelchairState::SEARCHING, true},
|
|
|
{WheelchairState::CHARGING, false}};
|
|
{WheelchairState::CHARGING, false}};
|
|
|
transition_table_["search_30s_timeout"] = search_timeout_perms;
|
|
transition_table_["search_30s_timeout"] = search_timeout_perms;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
RCLCPP_INFO(node_->get_logger(), "状态转移表已初始化完成");
|
|
RCLCPP_INFO(node_->get_logger(), "状态转移表已初始化完成");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -181,7 +184,7 @@ bool WorkflowManager::handleEvent(const std::string &event)
|
|
|
getCurrentState().c_str());
|
|
getCurrentState().c_str());
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
executeEvent(event);
|
|
executeEvent(event);
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
@@ -193,21 +196,21 @@ bool WorkflowManager::checkEventPermission(const std::string &event)
|
|
|
RCLCPP_WARN(node_->get_logger(), "未知事件: %s", event.c_str());
|
|
RCLCPP_WARN(node_->get_logger(), "未知事件: %s", event.c_str());
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
std::map<WheelchairState, bool> state_permissions = transition_table_[event];
|
|
std::map<WheelchairState, bool> state_permissions = transition_table_[event];
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (state_permissions.find(current_state_) != state_permissions.end())
|
|
if (state_permissions.find(current_state_) != state_permissions.end())
|
|
|
{
|
|
{
|
|
|
return state_permissions[current_state_];
|
|
return state_permissions[current_state_];
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::executeEvent(const std::string &event)
|
|
void WorkflowManager::executeEvent(const std::string &event)
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "执行事件: %s", event.c_str());
|
|
RCLCPP_INFO(node_->get_logger(), "执行事件: %s", event.c_str());
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据事件类型执行相应处理
|
|
// 根据事件类型执行相应处理
|
|
|
if (event == "ipad_phone_interface_start")
|
|
if (event == "ipad_phone_interface_start")
|
|
|
{
|
|
{
|
|
@@ -279,12 +282,13 @@ void WorkflowManager::executeEvent(const std::string &event)
|
|
|
}
|
|
}
|
|
|
else if (event == "search_30s_timeout")
|
|
else if (event == "search_30s_timeout")
|
|
|
{
|
|
{
|
|
|
- // 由外部回调处理
|
|
|
|
|
|
|
+ // 搜索超时事件
|
|
|
|
|
+ handleSearchTimeoutEvent();
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据事件触发状态转移
|
|
// 根据事件触发状态转移
|
|
|
processStateTransition(event);
|
|
processStateTransition(event);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState(event, "事件已处理");
|
|
publishState(event, "事件已处理");
|
|
|
}
|
|
}
|
|
@@ -304,7 +308,7 @@ void WorkflowManager::processStateTransition(const std::string &event)
|
|
|
transitionToWalking();
|
|
transitionToWalking();
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
case WheelchairState::WALKING:
|
|
case WheelchairState::WALKING:
|
|
|
if (event == "joystick_stop" || event == "push_stop" || event == "lock_vehicle")
|
|
if (event == "joystick_stop" || event == "push_stop" || event == "lock_vehicle")
|
|
|
{
|
|
{
|
|
@@ -319,9 +323,9 @@ void WorkflowManager::processStateTransition(const std::string &event)
|
|
|
transitionToCharging();
|
|
transitionToCharging();
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
case WheelchairState::SEARCHING:
|
|
case WheelchairState::SEARCHING:
|
|
|
- if (event == "search_30s_timeout" || event == "base_station_lost")
|
|
|
|
|
|
|
+ if (event == "base_station_lost")
|
|
|
{
|
|
{
|
|
|
transitionToReady();
|
|
transitionToReady();
|
|
|
}
|
|
}
|
|
@@ -333,8 +337,15 @@ void WorkflowManager::processStateTransition(const std::string &event)
|
|
|
{
|
|
{
|
|
|
transitionToWalking();
|
|
transitionToWalking();
|
|
|
}
|
|
}
|
|
|
|
|
+ // 搜索超时事件
|
|
|
|
|
+ else if (event == "search_30s_timeout")
|
|
|
|
|
+ {
|
|
|
|
|
+ RCLCPP_WARN(node_->get_logger(), "搜索30秒超时,回充失败");
|
|
|
|
|
+ // 触发回充失败处理
|
|
|
|
|
+ handleRechargeFailure("搜索30秒超时");
|
|
|
|
|
+ }
|
|
|
break;
|
|
break;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
case WheelchairState::CHARGING:
|
|
case WheelchairState::CHARGING:
|
|
|
if (event == "battery_full" ||
|
|
if (event == "battery_full" ||
|
|
|
event == "battery_stop_charging" ||
|
|
event == "battery_stop_charging" ||
|
|
@@ -371,18 +382,24 @@ void WorkflowManager::transitionToSearching()
|
|
|
RCLCPP_INFO(node_->get_logger(), "开始搜索充电站");
|
|
RCLCPP_INFO(node_->get_logger(), "开始搜索充电站");
|
|
|
publishState("SEARCH_CHARGING_STATION_START");
|
|
publishState("SEARCH_CHARGING_STATION_START");
|
|
|
startSearchTimeoutTimer();
|
|
startSearchTimeoutTimer();
|
|
|
|
|
+
|
|
|
|
|
+ // 发布回充开始通知
|
|
|
|
|
+ publishRechargeStatus("RECHARGE_STARTED", "回充功能已启动,正在搜索充电站");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::transitionToCharging()
|
|
void WorkflowManager::transitionToCharging()
|
|
|
{
|
|
{
|
|
|
- if (current_state_ == WheelchairState::SEARCHING ||
|
|
|
|
|
|
|
+ if (current_state_ == WheelchairState::SEARCHING ||
|
|
|
current_state_ == WheelchairState::WALKING)
|
|
current_state_ == WheelchairState::WALKING)
|
|
|
{
|
|
{
|
|
|
setState(WheelchairState::CHARGING);
|
|
setState(WheelchairState::CHARGING);
|
|
|
RCLCPP_INFO(node_->get_logger(), "开始充电");
|
|
RCLCPP_INFO(node_->get_logger(), "开始充电");
|
|
|
stopSearchTimeoutTimer();
|
|
stopSearchTimeoutTimer();
|
|
|
publishState("CHARGING_START");
|
|
publishState("CHARGING_START");
|
|
|
|
|
+
|
|
|
|
|
+ // 发布回充成功通知
|
|
|
|
|
+ publishRechargeStatus("RECHARGE_SUCCESS", "成功对接充电站,开始充电");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -391,7 +408,7 @@ void WorkflowManager::transitionToReady()
|
|
|
std::string previous_state = getCurrentState();
|
|
std::string previous_state = getCurrentState();
|
|
|
setState(WheelchairState::READY);
|
|
setState(WheelchairState::READY);
|
|
|
stopSearchTimeoutTimer();
|
|
stopSearchTimeoutTimer();
|
|
|
- RCLCPP_INFO(node_->get_logger(), "返回到就绪状态 (前状态: %s)",
|
|
|
|
|
|
|
+ RCLCPP_INFO(node_->get_logger(), "返回到就绪状态 (前状态: %s)",
|
|
|
previous_state.c_str());
|
|
previous_state.c_str());
|
|
|
publishState("WHEELCHAIR_READY");
|
|
publishState("WHEELCHAIR_READY");
|
|
|
}
|
|
}
|
|
@@ -401,10 +418,10 @@ void WorkflowManager::transitionToReady()
|
|
|
void WorkflowManager::processIpadStartEvent()
|
|
void WorkflowManager::processIpadStartEvent()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理iPad启动事件");
|
|
RCLCPP_INFO(node_->get_logger(), "处理iPad启动事件");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("IPAD_RECHARGE_STARTED", "iPad启动自主回充");
|
|
publishState("IPAD_RECHARGE_STARTED", "iPad启动自主回充");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 如果当前是就绪状态,自动转移到搜索状态
|
|
// 如果当前是就绪状态,自动转移到搜索状态
|
|
|
if (current_state_ == WheelchairState::READY)
|
|
if (current_state_ == WheelchairState::READY)
|
|
|
{
|
|
{
|
|
@@ -412,34 +429,37 @@ void WorkflowManager::processIpadStartEvent()
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- RCLCPP_WARN(node_->get_logger(),
|
|
|
|
|
- "当前状态 %s 无法启动回充", getCurrentState().c_str());
|
|
|
|
|
|
|
+ RCLCPP_WARN(node_->get_logger(),
|
|
|
|
|
+ "当前状态 %s 无法启动回充", getCurrentState().c_str());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::processIpadCancelEvent()
|
|
void WorkflowManager::processIpadCancelEvent()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理iPad取消事件");
|
|
RCLCPP_INFO(node_->get_logger(), "处理iPad取消事件");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("IPAD_RECHARGE_CANCELLED", "iPad取消自主回充");
|
|
publishState("IPAD_RECHARGE_CANCELLED", "iPad取消自主回充");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据当前状态决定是否取消回充
|
|
// 根据当前状态决定是否取消回充
|
|
|
- if (current_state_ == WheelchairState::SEARCHING ||
|
|
|
|
|
|
|
+ if (current_state_ == WheelchairState::SEARCHING ||
|
|
|
current_state_ == WheelchairState::CHARGING)
|
|
current_state_ == WheelchairState::CHARGING)
|
|
|
{
|
|
{
|
|
|
transitionToReady();
|
|
transitionToReady();
|
|
|
RCLCPP_INFO(node_->get_logger(), "iPad自主回充已取消,返回到就绪状态");
|
|
RCLCPP_INFO(node_->get_logger(), "iPad自主回充已取消,返回到就绪状态");
|
|
|
|
|
+
|
|
|
|
|
+ // 发布回充取消通知
|
|
|
|
|
+ publishRechargeStatus("RECHARGE_CANCELLED", "用户取消回充");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::processBluetoothDisconnected()
|
|
void WorkflowManager::processBluetoothDisconnected()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理蓝牙断开事件");
|
|
RCLCPP_INFO(node_->get_logger(), "处理蓝牙断开事件");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("BLUETOOTH_DISCONNECTED", "蓝牙连接已断开");
|
|
publishState("BLUETOOTH_DISCONNECTED", "蓝牙连接已断开");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据状态处理蓝牙断开
|
|
// 根据状态处理蓝牙断开
|
|
|
if (current_state_ == WheelchairState::WALKING ||
|
|
if (current_state_ == WheelchairState::WALKING ||
|
|
|
current_state_ == WheelchairState::SEARCHING ||
|
|
current_state_ == WheelchairState::SEARCHING ||
|
|
@@ -447,16 +467,22 @@ void WorkflowManager::processBluetoothDisconnected()
|
|
|
{
|
|
{
|
|
|
RCLCPP_WARN(node_->get_logger(), "蓝牙断开,返回到就绪状态");
|
|
RCLCPP_WARN(node_->get_logger(), "蓝牙断开,返回到就绪状态");
|
|
|
transitionToReady();
|
|
transitionToReady();
|
|
|
|
|
+
|
|
|
|
|
+ // 如果正在回充,发布回充失败通知
|
|
|
|
|
+ if (current_state_ == WheelchairState::SEARCHING)
|
|
|
|
|
+ {
|
|
|
|
|
+ publishRechargeStatus("RECHARGE_FAILED", "蓝牙断开导致回充失败");
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::processBluetoothConnected()
|
|
void WorkflowManager::processBluetoothConnected()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理蓝牙连接成功事件");
|
|
RCLCPP_INFO(node_->get_logger(), "处理蓝牙连接成功事件");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("BLUETOOTH_CONNECTED", "蓝牙连接成功");
|
|
publishState("BLUETOOTH_CONNECTED", "蓝牙连接成功");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 蓝牙连接成功通常不需要改变当前状态
|
|
// 蓝牙连接成功通常不需要改变当前状态
|
|
|
// 但可以根据业务需求添加逻辑
|
|
// 但可以根据业务需求添加逻辑
|
|
|
}
|
|
}
|
|
@@ -464,27 +490,33 @@ void WorkflowManager::processBluetoothConnected()
|
|
|
void WorkflowManager::processBaseStationPowerOff()
|
|
void WorkflowManager::processBaseStationPowerOff()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理基站断电事件");
|
|
RCLCPP_INFO(node_->get_logger(), "处理基站断电事件");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("BASE_STATION_POWER_OFF", "充电基站断电");
|
|
publishState("BASE_STATION_POWER_OFF", "充电基站断电");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据状态处理基站断电
|
|
// 根据状态处理基站断电
|
|
|
if (current_state_ == WheelchairState::SEARCHING)
|
|
if (current_state_ == WheelchairState::SEARCHING)
|
|
|
{
|
|
{
|
|
|
RCLCPP_WARN(node_->get_logger(), "基站断电,停止搜索");
|
|
RCLCPP_WARN(node_->get_logger(), "基站断电,停止搜索");
|
|
|
transitionToReady();
|
|
transitionToReady();
|
|
|
|
|
+
|
|
|
|
|
+ // 发布回充失败通知
|
|
|
|
|
+ publishRechargeStatus("RECHARGE_FAILED", "基站断电导致回充失败");
|
|
|
}
|
|
}
|
|
|
else if (current_state_ == WheelchairState::CHARGING)
|
|
else if (current_state_ == WheelchairState::CHARGING)
|
|
|
{
|
|
{
|
|
|
RCLCPP_ERROR(node_->get_logger(), "充电中基站断电!");
|
|
RCLCPP_ERROR(node_->get_logger(), "充电中基站断电!");
|
|
|
transitionToReady();
|
|
transitionToReady();
|
|
|
|
|
+
|
|
|
|
|
+ // 发布充电中断通知
|
|
|
|
|
+ publishRechargeStatus("CHARGING_INTERRUPTED", "基站断电导致充电中断");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::handleLowBatteryEvent(BatteryState state, float percentage)
|
|
void WorkflowManager::handleLowBatteryEvent(BatteryState state, float percentage)
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理低电量事件: %.1f%%", percentage);
|
|
RCLCPP_INFO(node_->get_logger(), "处理低电量事件: %.1f%%", percentage);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布相应的事件名称
|
|
// 发布相应的事件名称
|
|
|
if (state == BatteryState::CRITICAL)
|
|
if (state == BatteryState::CRITICAL)
|
|
|
{
|
|
{
|
|
@@ -494,13 +526,13 @@ void WorkflowManager::handleLowBatteryEvent(BatteryState state, float percentage
|
|
|
{
|
|
{
|
|
|
triggerEvent("low_battery_warning");
|
|
triggerEvent("low_battery_warning");
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据电池状态采取行动
|
|
// 根据电池状态采取行动
|
|
|
if (state == BatteryState::CRITICAL)
|
|
if (state == BatteryState::CRITICAL)
|
|
|
{
|
|
{
|
|
|
RCLCPP_ERROR(node_->get_logger(), "严重低电量! 自动启动回充搜索");
|
|
RCLCPP_ERROR(node_->get_logger(), "严重低电量! 自动启动回充搜索");
|
|
|
publishState("CRITICAL_BATTERY_EMERGENCY", "自动启动回充");
|
|
publishState("CRITICAL_BATTERY_EMERGENCY", "自动启动回充");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 紧急情况下,无论当前状态如何都尝试启动回充
|
|
// 紧急情况下,无论当前状态如何都尝试启动回充
|
|
|
if (current_state_ == WheelchairState::READY)
|
|
if (current_state_ == WheelchairState::READY)
|
|
|
{
|
|
{
|
|
@@ -512,7 +544,6 @@ void WorkflowManager::handleLowBatteryEvent(BatteryState state, float percentage
|
|
|
RCLCPP_WARN(node_->get_logger(), "严重低电量,停止行走并启动回充搜索");
|
|
RCLCPP_WARN(node_->get_logger(), "严重低电量,停止行走并启动回充搜索");
|
|
|
transitionToReady();
|
|
transitionToReady();
|
|
|
// 短暂延迟后启动搜索
|
|
// 短暂延迟后启动搜索
|
|
|
- // 注意:在实际应用中可能需要异步处理
|
|
|
|
|
transitionToSearching();
|
|
transitionToSearching();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -520,7 +551,7 @@ void WorkflowManager::handleLowBatteryEvent(BatteryState state, float percentage
|
|
|
{
|
|
{
|
|
|
RCLCPP_WARN(node_->get_logger(), "低电量警告,建议启动回充");
|
|
RCLCPP_WARN(node_->get_logger(), "低电量警告,建议启动回充");
|
|
|
publishState("LOW_BATTERY_WARNING", "建议启动回充");
|
|
publishState("LOW_BATTERY_WARNING", "建议启动回充");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 如果当前是就绪状态,自动启动回充
|
|
// 如果当前是就绪状态,自动启动回充
|
|
|
if (current_state_ == WheelchairState::READY)
|
|
if (current_state_ == WheelchairState::READY)
|
|
|
{
|
|
{
|
|
@@ -533,10 +564,10 @@ void WorkflowManager::handleLowBatteryEvent(BatteryState state, float percentage
|
|
|
void WorkflowManager::processLockVehicle()
|
|
void WorkflowManager::processLockVehicle()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理锁车操作");
|
|
RCLCPP_INFO(node_->get_logger(), "处理锁车操作");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("VEHICLE_LOCKED", "轮椅已锁定");
|
|
publishState("VEHICLE_LOCKED", "轮椅已锁定");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据状态处理锁车
|
|
// 根据状态处理锁车
|
|
|
if (current_state_ == WheelchairState::WALKING)
|
|
if (current_state_ == WheelchairState::WALKING)
|
|
|
{
|
|
{
|
|
@@ -547,6 +578,9 @@ void WorkflowManager::processLockVehicle()
|
|
|
{
|
|
{
|
|
|
RCLCPP_WARN(node_->get_logger(), "搜索中锁车,取消搜索");
|
|
RCLCPP_WARN(node_->get_logger(), "搜索中锁车,取消搜索");
|
|
|
transitionToReady();
|
|
transitionToReady();
|
|
|
|
|
+
|
|
|
|
|
+ // 发布回充取消通知
|
|
|
|
|
+ publishRechargeStatus("RECHARGE_CANCELLED", "锁车操作取消回充");
|
|
|
}
|
|
}
|
|
|
else if (current_state_ == WheelchairState::CHARGING)
|
|
else if (current_state_ == WheelchairState::CHARGING)
|
|
|
{
|
|
{
|
|
@@ -558,10 +592,10 @@ void WorkflowManager::processLockVehicle()
|
|
|
void WorkflowManager::processUnlockVehicle()
|
|
void WorkflowManager::processUnlockVehicle()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理解锁操作");
|
|
RCLCPP_INFO(node_->get_logger(), "处理解锁操作");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("VEHICLE_UNLOCKED", "轮椅已解锁");
|
|
publishState("VEHICLE_UNLOCKED", "轮椅已解锁");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据状态处理解锁
|
|
// 根据状态处理解锁
|
|
|
if (current_state_ == WheelchairState::READY)
|
|
if (current_state_ == WheelchairState::READY)
|
|
|
{
|
|
{
|
|
@@ -573,25 +607,28 @@ void WorkflowManager::processUnlockVehicle()
|
|
|
void WorkflowManager::processJoystickPullBack()
|
|
void WorkflowManager::processJoystickPullBack()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理摇杆后拉操作");
|
|
RCLCPP_INFO(node_->get_logger(), "处理摇杆后拉操作");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("JOYSTICK_PULL_BACK", "摇杆后拉");
|
|
publishState("JOYSTICK_PULL_BACK", "摇杆后拉");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据状态处理摇杆后拉
|
|
// 根据状态处理摇杆后拉
|
|
|
if (current_state_ == WheelchairState::SEARCHING)
|
|
if (current_state_ == WheelchairState::SEARCHING)
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "搜索中摇杆后拉,切换为行走模式");
|
|
RCLCPP_INFO(node_->get_logger(), "搜索中摇杆后拉,切换为行走模式");
|
|
|
transitionToWalking();
|
|
transitionToWalking();
|
|
|
|
|
+
|
|
|
|
|
+ // 发布回充取消通知
|
|
|
|
|
+ publishRechargeStatus("RECHARGE_CANCELLED", "用户手动中断回充");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::processJoystickStop()
|
|
void WorkflowManager::processJoystickStop()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理摇杆停止操作");
|
|
RCLCPP_INFO(node_->get_logger(), "处理摇杆停止操作");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("JOYSTICK_STOP", "摇杆停止");
|
|
publishState("JOYSTICK_STOP", "摇杆停止");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据状态处理摇杆停止
|
|
// 根据状态处理摇杆停止
|
|
|
if (current_state_ == WheelchairState::WALKING)
|
|
if (current_state_ == WheelchairState::WALKING)
|
|
|
{
|
|
{
|
|
@@ -602,31 +639,37 @@ void WorkflowManager::processJoystickStop()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "搜索中摇杆停止,返回就绪状态");
|
|
RCLCPP_INFO(node_->get_logger(), "搜索中摇杆停止,返回就绪状态");
|
|
|
transitionToReady();
|
|
transitionToReady();
|
|
|
|
|
+
|
|
|
|
|
+ // 发布回充取消通知
|
|
|
|
|
+ publishRechargeStatus("RECHARGE_CANCELLED", "用户停止操作取消回充");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::processPushStart()
|
|
void WorkflowManager::processPushStart()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理推行启动");
|
|
RCLCPP_INFO(node_->get_logger(), "处理推行启动");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("PUSH_START", "推行模式启动");
|
|
publishState("PUSH_START", "推行模式启动");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据状态处理推行启动
|
|
// 根据状态处理推行启动
|
|
|
if (current_state_ == WheelchairState::CHARGING)
|
|
if (current_state_ == WheelchairState::CHARGING)
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "充电中启动推行,切换到行走模式");
|
|
RCLCPP_INFO(node_->get_logger(), "充电中启动推行,切换到行走模式");
|
|
|
transitionToWalking();
|
|
transitionToWalking();
|
|
|
|
|
+
|
|
|
|
|
+ // 发布充电中断通知
|
|
|
|
|
+ publishRechargeStatus("CHARGING_INTERRUPTED", "推行操作中断充电");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::processPushStop()
|
|
void WorkflowManager::processPushStop()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理推行停止");
|
|
RCLCPP_INFO(node_->get_logger(), "处理推行停止");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("PUSH_STOP", "推行模式停止");
|
|
publishState("PUSH_STOP", "推行模式停止");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据状态处理推行停止
|
|
// 根据状态处理推行停止
|
|
|
if (current_state_ == WheelchairState::WALKING)
|
|
if (current_state_ == WheelchairState::WALKING)
|
|
|
{
|
|
{
|
|
@@ -643,13 +686,13 @@ void WorkflowManager::processPushStop()
|
|
|
void WorkflowManager::handleChargingStartEvent()
|
|
void WorkflowManager::handleChargingStartEvent()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理充电开始事件");
|
|
RCLCPP_INFO(node_->get_logger(), "处理充电开始事件");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 触发相应事件
|
|
// 触发相应事件
|
|
|
triggerEvent("battery_start_charging");
|
|
triggerEvent("battery_start_charging");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("BATTERY_START_CHARGING", "开始充电");
|
|
publishState("BATTERY_START_CHARGING", "开始充电");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 如果当前在搜索状态,转移到充电状态
|
|
// 如果当前在搜索状态,转移到充电状态
|
|
|
if (current_state_ == WheelchairState::SEARCHING)
|
|
if (current_state_ == WheelchairState::SEARCHING)
|
|
|
{
|
|
{
|
|
@@ -665,66 +708,74 @@ void WorkflowManager::handleChargingStartEvent()
|
|
|
void WorkflowManager::handleChargingStopEvent()
|
|
void WorkflowManager::handleChargingStopEvent()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理充电停止事件");
|
|
RCLCPP_INFO(node_->get_logger(), "处理充电停止事件");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 触发相应事件
|
|
// 触发相应事件
|
|
|
triggerEvent("battery_stop_charging");
|
|
triggerEvent("battery_stop_charging");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("BATTERY_STOP_CHARGING", "停止充电");
|
|
publishState("BATTERY_STOP_CHARGING", "停止充电");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 如果当前在充电状态,返回就绪状态
|
|
// 如果当前在充电状态,返回就绪状态
|
|
|
if (current_state_ == WheelchairState::CHARGING)
|
|
if (current_state_ == WheelchairState::CHARGING)
|
|
|
{
|
|
{
|
|
|
RCLCPP_WARN(node_->get_logger(), "充电停止,返回就绪状态");
|
|
RCLCPP_WARN(node_->get_logger(), "充电停止,返回就绪状态");
|
|
|
transitionToReady();
|
|
transitionToReady();
|
|
|
|
|
+
|
|
|
|
|
+ // 发布充电停止通知
|
|
|
|
|
+ publishRechargeStatus("CHARGING_STOPPED", "充电已停止");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::handleChargingFullEvent()
|
|
void WorkflowManager::handleChargingFullEvent()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理电池充满事件");
|
|
RCLCPP_INFO(node_->get_logger(), "处理电池充满事件");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 触发相应事件
|
|
// 触发相应事件
|
|
|
triggerEvent("battery_full");
|
|
triggerEvent("battery_full");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("BATTERY_FULL", "电池已充满");
|
|
publishState("BATTERY_FULL", "电池已充满");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 停止充电,返回就绪状态
|
|
// 停止充电,返回就绪状态
|
|
|
if (current_state_ == WheelchairState::CHARGING)
|
|
if (current_state_ == WheelchairState::CHARGING)
|
|
|
{
|
|
{
|
|
|
transitionToReady();
|
|
transitionToReady();
|
|
|
|
|
+
|
|
|
|
|
+ // 发布充电完成通知
|
|
|
|
|
+ publishRechargeStatus("CHARGING_COMPLETED", "电池已充满,充电完成");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::processErrorCode()
|
|
void WorkflowManager::processErrorCode()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理错误码");
|
|
RCLCPP_INFO(node_->get_logger(), "处理错误码");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("ERROR_CODE_HANDLING", "处理系统错误码");
|
|
publishState("ERROR_CODE_HANDLING", "处理系统错误码");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据错误码的严重程度处理
|
|
// 根据错误码的严重程度处理
|
|
|
- // 严重错误可能需要紧急停止并返回就绪状态
|
|
|
|
|
bool critical_error = true; // 示例:假设是严重错误
|
|
bool critical_error = true; // 示例:假设是严重错误
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (critical_error)
|
|
if (critical_error)
|
|
|
{
|
|
{
|
|
|
RCLCPP_ERROR(node_->get_logger(), "检测到严重错误,紧急停止所有操作");
|
|
RCLCPP_ERROR(node_->get_logger(), "检测到严重错误,紧急停止所有操作");
|
|
|
transitionToReady();
|
|
transitionToReady();
|
|
|
|
|
+
|
|
|
|
|
+ // 发布回充失败通知
|
|
|
|
|
+ publishRechargeStatus("RECHARGE_FAILED", "系统错误导致回充失败");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::handleBaseStationLostEvent()
|
|
void WorkflowManager::handleBaseStationLostEvent()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理基站丢失事件");
|
|
RCLCPP_INFO(node_->get_logger(), "处理基站丢失事件");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 触发相应事件
|
|
// 触发相应事件
|
|
|
triggerEvent("base_station_lost");
|
|
triggerEvent("base_station_lost");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态更新
|
|
// 发布状态更新
|
|
|
publishState("CHARGING_STATION_LOST", "充电基站丢失");
|
|
publishState("CHARGING_STATION_LOST", "充电基站丢失");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据状态处理基站丢失
|
|
// 根据状态处理基站丢失
|
|
|
if (current_state_ == WheelchairState::WALKING)
|
|
if (current_state_ == WheelchairState::WALKING)
|
|
|
{
|
|
{
|
|
@@ -734,29 +785,93 @@ void WorkflowManager::handleBaseStationLostEvent()
|
|
|
else if (current_state_ == WheelchairState::SEARCHING)
|
|
else if (current_state_ == WheelchairState::SEARCHING)
|
|
|
{
|
|
{
|
|
|
// 搜索中检测到基站丢失,返回就绪状态
|
|
// 搜索中检测到基站丢失,返回就绪状态
|
|
|
|
|
+ RCLCPP_WARN(node_->get_logger(), "搜索中基站丢失,返回就绪状态");
|
|
|
transitionToReady();
|
|
transitionToReady();
|
|
|
|
|
+
|
|
|
|
|
+ // 发布回充失败通知
|
|
|
|
|
+ publishRechargeStatus("RECHARGE_FAILED", "基站丢失导致回充失败");
|
|
|
}
|
|
}
|
|
|
else if (current_state_ == WheelchairState::CHARGING)
|
|
else if (current_state_ == WheelchairState::CHARGING)
|
|
|
{
|
|
{
|
|
|
RCLCPP_ERROR(node_->get_logger(), "充电中基站丢失,停止充电");
|
|
RCLCPP_ERROR(node_->get_logger(), "充电中基站丢失,停止充电");
|
|
|
transitionToReady();
|
|
transitionToReady();
|
|
|
|
|
+
|
|
|
|
|
+ // 发布充电中断通知
|
|
|
|
|
+ publishRechargeStatus("CHARGING_INTERRUPTED", "基站丢失导致充电中断");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::handleSearchTimeoutEvent()
|
|
void WorkflowManager::handleSearchTimeoutEvent()
|
|
|
{
|
|
{
|
|
|
RCLCPP_INFO(node_->get_logger(), "处理搜索超时事件");
|
|
RCLCPP_INFO(node_->get_logger(), "处理搜索超时事件");
|
|
|
-
|
|
|
|
|
- // 触发相应事件
|
|
|
|
|
- triggerEvent("search_30s_timeout");
|
|
|
|
|
-
|
|
|
|
|
- // 发布超时通知
|
|
|
|
|
- publishState("SEARCH_CHARGING_STATION_TIMEOUT", "搜索充电站超时");
|
|
|
|
|
-
|
|
|
|
|
- // 根据状态转移表,搜索超时应返回就绪状态
|
|
|
|
|
- if (current_state_ == WheelchairState::SEARCHING)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 搜索超时30秒视为回充失败
|
|
|
|
|
+ RCLCPP_WARN(node_->get_logger(), "搜索30秒超时,回充失败");
|
|
|
|
|
+
|
|
|
|
|
+ // 发布回充失败通知
|
|
|
|
|
+ publishRechargeStatus("RECHARGE_FAILED", "搜索充电站30秒超时");
|
|
|
|
|
+
|
|
|
|
|
+ // 生成回充失败错误码
|
|
|
|
|
+ publishRechargeErrorCode(0x51010101); // 回充检测失败(超时)
|
|
|
|
|
+
|
|
|
|
|
+ // 触发基站丢失事件(保持向后兼容)
|
|
|
|
|
+ handleBaseStationLostEvent();
|
|
|
|
|
+
|
|
|
|
|
+ RCLCPP_INFO(node_->get_logger(), "搜索30秒超时,已作为回充失败事件处理");
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void WorkflowManager::handleRechargeFailure(const std::string &reason)
|
|
|
|
|
+{
|
|
|
|
|
+ RCLCPP_WARN(node_->get_logger(), "回充失败: %s", reason.c_str());
|
|
|
|
|
+
|
|
|
|
|
+ // 发布回充失败通知
|
|
|
|
|
+ publishRechargeStatus("RECHARGE_FAILED", "回充失败: " + reason);
|
|
|
|
|
+
|
|
|
|
|
+ // 生成回充失败错误码
|
|
|
|
|
+ publishRechargeErrorCode(0x51010101); // 回充检测失败
|
|
|
|
|
+
|
|
|
|
|
+ // 返回就绪状态
|
|
|
|
|
+ transitionToReady();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// ==================== 回充状态管理 ====================
|
|
|
|
|
+
|
|
|
|
|
+void WorkflowManager::publishRechargeStatus(const std::string &status, const std::string &message)
|
|
|
|
|
+{
|
|
|
|
|
+ // 发布到专用话题
|
|
|
|
|
+ auto msg = std_msgs::msg::String();
|
|
|
|
|
+ msg.data = status + ": " + message;
|
|
|
|
|
+ recharge_timeout_publisher_->publish(msg);
|
|
|
|
|
+
|
|
|
|
|
+ // 同时记录日志
|
|
|
|
|
+ RCLCPP_INFO(node_->get_logger(), "[回充状态] %s: %s", status.c_str(), message.c_str());
|
|
|
|
|
+
|
|
|
|
|
+ // 调用外部回调(如果有)
|
|
|
|
|
+ if (recharge_status_callback_)
|
|
|
{
|
|
{
|
|
|
- transitionToReady();
|
|
|
|
|
|
|
+ recharge_status_callback_(status, message);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void WorkflowManager::publishRechargeErrorCode(uint32_t error_code)
|
|
|
|
|
+{
|
|
|
|
|
+ // 创建错误码消息
|
|
|
|
|
+ auto error_msg = std_msgs::msg::UInt32();
|
|
|
|
|
+ error_msg.data = error_code;
|
|
|
|
|
+
|
|
|
|
|
+ // 发布到错误码话题
|
|
|
|
|
+ // 注意:这里需要外部提供错误码发布者,或者通过回调传递
|
|
|
|
|
+
|
|
|
|
|
+ RCLCPP_WARN(node_->get_logger(), "生成回充错误码: 0x%08X", error_code);
|
|
|
|
|
+
|
|
|
|
|
+ // 调用外部错误处理回调(如果有)
|
|
|
|
|
+ if (recharge_error_callback_)
|
|
|
|
|
+ {
|
|
|
|
|
+ ErrorInfo error_info;
|
|
|
|
|
+ error_info.error_code = error_code;
|
|
|
|
|
+ error_info.description = "回充功能失败";
|
|
|
|
|
+ error_info.timestamp = node_->now().nanoseconds() / 1000000;
|
|
|
|
|
+ recharge_error_callback_(error_info);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -769,7 +884,7 @@ void WorkflowManager::startSearchTimeoutTimer()
|
|
|
{
|
|
{
|
|
|
search_timeout_timer_->cancel();
|
|
search_timeout_timer_->cancel();
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 创建30秒定时器
|
|
// 创建30秒定时器
|
|
|
search_timeout_timer_ = node_->create_wall_timer(
|
|
search_timeout_timer_ = node_->create_wall_timer(
|
|
|
std::chrono::seconds(30),
|
|
std::chrono::seconds(30),
|
|
@@ -777,8 +892,8 @@ void WorkflowManager::startSearchTimeoutTimer()
|
|
|
{
|
|
{
|
|
|
this->searchTimeoutCallback();
|
|
this->searchTimeoutCallback();
|
|
|
});
|
|
});
|
|
|
-
|
|
|
|
|
- RCLCPP_INFO(node_->get_logger(), "搜索超时定时器已启动");
|
|
|
|
|
|
|
+
|
|
|
|
|
+ RCLCPP_INFO(node_->get_logger(), "搜索超时定时器已启动 (30秒)");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WorkflowManager::stopSearchTimeoutTimer()
|
|
void WorkflowManager::stopSearchTimeoutTimer()
|
|
@@ -795,9 +910,14 @@ void WorkflowManager::searchTimeoutCallback()
|
|
|
{
|
|
{
|
|
|
if (current_state_ == WheelchairState::SEARCHING)
|
|
if (current_state_ == WheelchairState::SEARCHING)
|
|
|
{
|
|
{
|
|
|
- RCLCPP_WARN(node_->get_logger(), "搜索充电站超时30秒");
|
|
|
|
|
|
|
+ RCLCPP_WARN(node_->get_logger(), "搜索充电站超时30秒,回充失败");
|
|
|
handleSearchTimeoutEvent();
|
|
handleSearchTimeoutEvent();
|
|
|
}
|
|
}
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ RCLCPP_DEBUG(node_->get_logger(), "搜索超时定时器触发,但当前不在搜索状态");
|
|
|
|
|
+ stopSearchTimeoutTimer();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ==================== 辅助函数 ====================
|
|
// ==================== 辅助函数 ====================
|
|
@@ -811,17 +931,17 @@ void WorkflowManager::setState(WheelchairState new_state)
|
|
|
{
|
|
{
|
|
|
std::string old_state = getCurrentState();
|
|
std::string old_state = getCurrentState();
|
|
|
current_state_ = new_state;
|
|
current_state_ = new_state;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
RCLCPP_INFO(node_->get_logger(),
|
|
RCLCPP_INFO(node_->get_logger(),
|
|
|
"状态转移: %s -> %s",
|
|
"状态转移: %s -> %s",
|
|
|
old_state.c_str(),
|
|
old_state.c_str(),
|
|
|
getCurrentState().c_str());
|
|
getCurrentState().c_str());
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 发布状态到ROS话题
|
|
// 发布状态到ROS话题
|
|
|
auto msg = std_msgs::msg::String();
|
|
auto msg = std_msgs::msg::String();
|
|
|
msg.data = getCurrentState();
|
|
msg.data = getCurrentState();
|
|
|
state_publisher_->publish(msg);
|
|
state_publisher_->publish(msg);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 调用外部回调
|
|
// 调用外部回调
|
|
|
if (state_update_callback_)
|
|
if (state_update_callback_)
|
|
|
{
|
|
{
|
|
@@ -858,7 +978,7 @@ void WorkflowManager::publishState(const std::string &state_str, const std::stri
|
|
|
msg.data = state_str + ":" + message;
|
|
msg.data = state_str + ":" + message;
|
|
|
}
|
|
}
|
|
|
state_publisher_->publish(msg);
|
|
state_publisher_->publish(msg);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 调用外部回调
|
|
// 调用外部回调
|
|
|
if (state_update_callback_)
|
|
if (state_update_callback_)
|
|
|
{
|
|
{
|
|
@@ -872,6 +992,20 @@ void WorkflowManager::setStateUpdateCallback(StateUpdateCallback callback)
|
|
|
RCLCPP_INFO(node_->get_logger(), "已设置状态更新回调");
|
|
RCLCPP_INFO(node_->get_logger(), "已设置状态更新回调");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 设置回充状态回调
|
|
|
|
|
+void WorkflowManager::setRechargeStatusCallback(StateUpdateCallback callback)
|
|
|
|
|
+{
|
|
|
|
|
+ recharge_status_callback_ = callback;
|
|
|
|
|
+ RCLCPP_INFO(node_->get_logger(), "已设置回充状态回调");
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 设置回充错误回调
|
|
|
|
|
+void WorkflowManager::setRechargeErrorCallback(std::function<void(const ErrorInfo &)> callback)
|
|
|
|
|
+{
|
|
|
|
|
+ recharge_error_callback_ = callback;
|
|
|
|
|
+ RCLCPP_INFO(node_->get_logger(), "已设置回充错误回调");
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// ==================== 内部事件触发 ====================
|
|
// ==================== 内部事件触发 ====================
|
|
|
|
|
|
|
|
void WorkflowManager::triggerEvent(const std::string &event_name)
|
|
void WorkflowManager::triggerEvent(const std::string &event_name)
|
|
@@ -885,7 +1019,7 @@ void WorkflowManager::triggerEvent(const std::string &event_name)
|
|
|
getCurrentState().c_str());
|
|
getCurrentState().c_str());
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 执行事件
|
|
// 执行事件
|
|
|
executeEvent(event_name);
|
|
executeEvent(event_name);
|
|
|
}
|
|
}
|