|
@@ -13,6 +13,9 @@ WorkflowManager::WorkflowManager(rclcpp::Node *node)
|
|
|
// 初始化状态转移表
|
|
// 初始化状态转移表
|
|
|
initializeTransitionTable();
|
|
initializeTransitionTable();
|
|
|
|
|
|
|
|
|
|
+ // 初始化旋转管理器
|
|
|
|
|
+ initializeRotationManager();
|
|
|
|
|
+
|
|
|
// 创建状态发布者
|
|
// 创建状态发布者
|
|
|
state_publisher_ = node_->create_publisher<std_msgs::msg::String>(
|
|
state_publisher_ = node_->create_publisher<std_msgs::msg::String>(
|
|
|
"wheelchair/state", 10);
|
|
"wheelchair/state", 10);
|
|
@@ -24,6 +27,12 @@ WorkflowManager::WorkflowManager(rclcpp::Node *node)
|
|
|
RCLCPP_INFO(node_->get_logger(), "工作流管理器已初始化");
|
|
RCLCPP_INFO(node_->get_logger(), "工作流管理器已初始化");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void WorkflowManager::initializeRotationManager()
|
|
|
|
|
+{
|
|
|
|
|
+ rotation_manager_ = std::make_unique<RotationManager>(node_);
|
|
|
|
|
+ RCLCPP_INFO(node_->get_logger(), "旋转管理器已初始化");
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void WorkflowManager::initializeTransitionTable()
|
|
void WorkflowManager::initializeTransitionTable()
|
|
|
{
|
|
{
|
|
|
transition_table_.clear();
|
|
transition_table_.clear();
|
|
@@ -32,6 +41,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> ipad_start_perms = {
|
|
std::map<WheelchairState, bool> ipad_start_perms = {
|
|
|
{WheelchairState::READY, true},
|
|
{WheelchairState::READY, true},
|
|
|
{WheelchairState::WALKING, false},
|
|
{WheelchairState::WALKING, false},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -40,6 +50,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> ipad_cancel_perms = {
|
|
std::map<WheelchairState, bool> ipad_cancel_perms = {
|
|
|
{WheelchairState::READY, true},
|
|
{WheelchairState::READY, true},
|
|
|
{WheelchairState::WALKING, true},
|
|
{WheelchairState::WALKING, true},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -48,6 +59,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> bluetooth_disconnect_perms = {
|
|
std::map<WheelchairState, bool> bluetooth_disconnect_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
|
{WheelchairState::WALKING, true},
|
|
{WheelchairState::WALKING, true},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -56,6 +68,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> bluetooth_connect_perms = {
|
|
std::map<WheelchairState, bool> bluetooth_connect_perms = {
|
|
|
{WheelchairState::READY, true},
|
|
{WheelchairState::READY, true},
|
|
|
{WheelchairState::WALKING, false},
|
|
{WheelchairState::WALKING, false},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -64,6 +77,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> base_power_off_perms = {
|
|
std::map<WheelchairState, bool> base_power_off_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
|
{WheelchairState::WALKING, true},
|
|
{WheelchairState::WALKING, true},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -72,6 +86,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> low_battery_perms = {
|
|
std::map<WheelchairState, bool> low_battery_perms = {
|
|
|
{WheelchairState::READY, true},
|
|
{WheelchairState::READY, true},
|
|
|
{WheelchairState::WALKING, false},
|
|
{WheelchairState::WALKING, false},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -80,6 +95,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> lock_vehicle_perms = {
|
|
std::map<WheelchairState, bool> lock_vehicle_perms = {
|
|
|
{WheelchairState::READY, true},
|
|
{WheelchairState::READY, true},
|
|
|
{WheelchairState::WALKING, false},
|
|
{WheelchairState::WALKING, false},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -88,6 +104,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> unlock_vehicle_perms = {
|
|
std::map<WheelchairState, bool> unlock_vehicle_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
|
{WheelchairState::WALKING, true},
|
|
{WheelchairState::WALKING, true},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -96,6 +113,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> joystick_pull_perms = {
|
|
std::map<WheelchairState, bool> joystick_pull_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
|
{WheelchairState::WALKING, false},
|
|
{WheelchairState::WALKING, false},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -104,6 +122,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> joystick_stop_perms = {
|
|
std::map<WheelchairState, bool> joystick_stop_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
|
{WheelchairState::WALKING, true},
|
|
{WheelchairState::WALKING, true},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -112,6 +131,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> push_start_perms = {
|
|
std::map<WheelchairState, bool> push_start_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
|
{WheelchairState::WALKING, false},
|
|
{WheelchairState::WALKING, false},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -120,6 +140,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> push_stop_perms = {
|
|
std::map<WheelchairState, bool> push_stop_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
|
{WheelchairState::WALKING, true},
|
|
{WheelchairState::WALKING, true},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -128,6 +149,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> battery_start_charging_perms = {
|
|
std::map<WheelchairState, bool> battery_start_charging_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
|
{WheelchairState::WALKING, false},
|
|
{WheelchairState::WALKING, false},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -136,6 +158,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> battery_stop_charging_perms = {
|
|
std::map<WheelchairState, bool> battery_stop_charging_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
|
{WheelchairState::WALKING, false},
|
|
{WheelchairState::WALKING, false},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -144,6 +167,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> battery_full_perms = {
|
|
std::map<WheelchairState, bool> battery_full_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
|
{WheelchairState::WALKING, false},
|
|
{WheelchairState::WALKING, false},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -152,6 +176,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> error_code_perms = {
|
|
std::map<WheelchairState, bool> error_code_perms = {
|
|
|
{WheelchairState::READY, true},
|
|
{WheelchairState::READY, true},
|
|
|
{WheelchairState::WALKING, true},
|
|
{WheelchairState::WALKING, true},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -160,6 +185,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> base_station_lost_perms = {
|
|
std::map<WheelchairState, bool> base_station_lost_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
|
{WheelchairState::WALKING, true},
|
|
{WheelchairState::WALKING, true},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -168,6 +194,7 @@ void WorkflowManager::initializeTransitionTable()
|
|
|
std::map<WheelchairState, bool> search_timeout_perms = {
|
|
std::map<WheelchairState, bool> search_timeout_perms = {
|
|
|
{WheelchairState::READY, false},
|
|
{WheelchairState::READY, false},
|
|
|
{WheelchairState::WALKING, false},
|
|
{WheelchairState::WALKING, false},
|
|
|
|
|
+ {WheelchairState::ROTATING, false}, // 旋转中❌
|
|
|
{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;
|
|
@@ -333,7 +360,10 @@ void WorkflowManager::processStateTransition(const std::string &event)
|
|
|
transitionToCharging();
|
|
transitionToCharging();
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
-
|
|
|
|
|
|
|
+ case WheelchairState::ROTATING:
|
|
|
|
|
+ // 旋转中状态下,所有事件默认不处理,可以添加特定逻辑
|
|
|
|
|
+ RCLCPP_DEBUG(node_->get_logger(), "旋转中状态下忽略事件: %s", event.c_str());
|
|
|
|
|
+ break;
|
|
|
case WheelchairState::SEARCHING:
|
|
case WheelchairState::SEARCHING:
|
|
|
if (event == "base_station_lost")
|
|
if (event == "base_station_lost")
|
|
|
{
|
|
{
|
|
@@ -376,15 +406,132 @@ void WorkflowManager::processStateTransition(const std::string &event)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// ==================== 旋转管理接口 ====================
|
|
|
|
|
+
|
|
|
|
|
+void WorkflowManager::startRotationTimer()
|
|
|
|
|
+{
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ // 创建10秒后检查旋转的定时器
|
|
|
|
|
+ rotation_check_timer_ = node_->create_wall_timer(
|
|
|
|
|
+ std::chrono::seconds(10),
|
|
|
|
|
+ [this]()
|
|
|
|
|
+ {
|
|
|
|
|
+ this->rotationCheckCallback();
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ RCLCPP_INFO(node_->get_logger(), "旋转检查定时器已启动 (10秒后检查)");
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (const std::exception &e)
|
|
|
|
|
+ {
|
|
|
|
|
+ handleException("启动旋转检查定时器", e);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void WorkflowManager::checkRotationTransition()
|
|
|
|
|
+{
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ if (current_state_ == WheelchairState::SEARCHING)
|
|
|
|
|
+ {
|
|
|
|
|
+ double search_duration = (node_->now() - search_start_time_).seconds();
|
|
|
|
|
+
|
|
|
|
|
+ // 如果搜索时间超过10秒,进入旋转状态
|
|
|
|
|
+ if (search_duration >= 10.0)
|
|
|
|
|
+ {
|
|
|
|
|
+ RCLCPP_INFO(node_->get_logger(),
|
|
|
|
|
+ "搜索已持续 %.1f 秒,进入旋转状态", search_duration);
|
|
|
|
|
+ transitionToRotating();
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ RCLCPP_DEBUG(node_->get_logger(),
|
|
|
|
|
+ "搜索中,已持续 %.1f 秒,还需 %.1f 秒进入旋转",
|
|
|
|
|
+ search_duration, 10.0 - search_duration);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (const std::exception &e)
|
|
|
|
|
+ {
|
|
|
|
|
+ handleException("检查旋转转移", e);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void WorkflowManager::stopRotationTimer()
|
|
|
|
|
+{
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ if (rotation_check_timer_)
|
|
|
|
|
+ {
|
|
|
|
|
+ rotation_check_timer_->cancel();
|
|
|
|
|
+ rotation_check_timer_.reset();
|
|
|
|
|
+ RCLCPP_INFO(node_->get_logger(), "旋转检查定时器已停止");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (const std::exception &e)
|
|
|
|
|
+ {
|
|
|
|
|
+ handleException("停止旋转检查定时器", e);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void WorkflowManager::transitionToRotating()
|
|
|
|
|
+{
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ if (current_state_ == WheelchairState::SEARCHING)
|
|
|
|
|
+ {
|
|
|
|
|
+ setState(WheelchairState::ROTATING);
|
|
|
|
|
+
|
|
|
|
|
+ // 启动旋转
|
|
|
|
|
+ if (rotation_manager_)
|
|
|
|
|
+ {
|
|
|
|
|
+ rotation_manager_->startRotation();
|
|
|
|
|
+ RCLCPP_INFO(node_->get_logger(), "轮椅开始旋转搜索");
|
|
|
|
|
+ publishState("WHEELCHAIR_ROTATING", "旋转搜索充电站");
|
|
|
|
|
+
|
|
|
|
|
+ // 发布回充状态
|
|
|
|
|
+ publishRechargeStatus("ROTATING_SEARCH",
|
|
|
|
|
+ "搜索10秒未找到基站,开始旋转搜索");
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ RCLCPP_ERROR(node_->get_logger(), "旋转管理器未初始化");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 停止旋转检查定时器
|
|
|
|
|
+ stopRotationTimer();
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ RCLCPP_WARN(node_->get_logger(),
|
|
|
|
|
+ "当前状态 %s 无法转换为旋转状态",
|
|
|
|
|
+ getCurrentState().c_str());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (const std::exception &e)
|
|
|
|
|
+ {
|
|
|
|
|
+ handleException("转换到旋转状态", e);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void WorkflowManager::transitionToWalking()
|
|
void WorkflowManager::transitionToWalking()
|
|
|
{
|
|
{
|
|
|
try
|
|
try
|
|
|
{
|
|
{
|
|
|
|
|
+ // 如果正在旋转,先停止旋转
|
|
|
|
|
+ if (rotation_manager_ && rotation_manager_->isRotating())
|
|
|
|
|
+ {
|
|
|
|
|
+ rotation_manager_->stopRotation();
|
|
|
|
|
+ }
|
|
|
if (current_state_ == WheelchairState::READY ||
|
|
if (current_state_ == WheelchairState::READY ||
|
|
|
current_state_ == WheelchairState::SEARCHING ||
|
|
current_state_ == WheelchairState::SEARCHING ||
|
|
|
- current_state_ == WheelchairState::CHARGING)
|
|
|
|
|
|
|
+ current_state_ == WheelchairState::CHARGING ||
|
|
|
|
|
+ current_state_ == WheelchairState::ROTATING)
|
|
|
{
|
|
{
|
|
|
setState(WheelchairState::WALKING);
|
|
setState(WheelchairState::WALKING);
|
|
|
|
|
+ // 停止所有定时器
|
|
|
|
|
+ stopSearchTimeoutTimer();
|
|
|
|
|
+ stopRotationTimer();
|
|
|
RCLCPP_INFO(node_->get_logger(), "轮椅开始行走");
|
|
RCLCPP_INFO(node_->get_logger(), "轮椅开始行走");
|
|
|
publishState("WHEELCHAIR_WALKING");
|
|
publishState("WHEELCHAIR_WALKING");
|
|
|
}
|
|
}
|
|
@@ -403,10 +550,11 @@ void WorkflowManager::transitionToSearching()
|
|
|
current_state_ == WheelchairState::WALKING)
|
|
current_state_ == WheelchairState::WALKING)
|
|
|
{
|
|
{
|
|
|
setState(WheelchairState::SEARCHING);
|
|
setState(WheelchairState::SEARCHING);
|
|
|
|
|
+ search_start_time_ = node_->now();
|
|
|
RCLCPP_INFO(node_->get_logger(), "开始搜索充电站");
|
|
RCLCPP_INFO(node_->get_logger(), "开始搜索充电站");
|
|
|
publishState("SEARCH_CHARGING_STATION_START");
|
|
publishState("SEARCH_CHARGING_STATION_START");
|
|
|
startSearchTimeoutTimer();
|
|
startSearchTimeoutTimer();
|
|
|
-
|
|
|
|
|
|
|
+ startRotationTimer();
|
|
|
// 发布回充开始通知
|
|
// 发布回充开始通知
|
|
|
publishRechargeStatus("RECHARGE_STARTED", "回充功能已启动,正在搜索充电站");
|
|
publishRechargeStatus("RECHARGE_STARTED", "回充功能已启动,正在搜索充电站");
|
|
|
}
|
|
}
|
|
@@ -446,6 +594,12 @@ void WorkflowManager::transitionToReady()
|
|
|
std::string previous_state = getCurrentState();
|
|
std::string previous_state = getCurrentState();
|
|
|
setState(WheelchairState::READY);
|
|
setState(WheelchairState::READY);
|
|
|
stopSearchTimeoutTimer();
|
|
stopSearchTimeoutTimer();
|
|
|
|
|
+ stopRotationTimer();
|
|
|
|
|
+ // 如果正在旋转,停止旋转
|
|
|
|
|
+ if (rotation_manager_ && rotation_manager_->isRotating())
|
|
|
|
|
+ {
|
|
|
|
|
+ rotation_manager_->stopRotation();
|
|
|
|
|
+ }
|
|
|
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");
|
|
@@ -975,6 +1129,16 @@ void WorkflowManager::emergencyTransitionToReady(const std::string &reason)
|
|
|
search_timeout_timer_->cancel();
|
|
search_timeout_timer_->cancel();
|
|
|
search_timeout_timer_.reset();
|
|
search_timeout_timer_.reset();
|
|
|
}
|
|
}
|
|
|
|
|
+ if (rotation_check_timer_)
|
|
|
|
|
+ {
|
|
|
|
|
+ rotation_check_timer_->cancel();
|
|
|
|
|
+ rotation_check_timer_.reset();
|
|
|
|
|
+ }
|
|
|
|
|
+ // 停止旋转
|
|
|
|
|
+ if (rotation_manager_ && rotation_manager_->isRotating())
|
|
|
|
|
+ {
|
|
|
|
|
+ rotation_manager_->stopRotation();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// 强制设置状态
|
|
// 强制设置状态
|
|
|
current_state_ = WheelchairState::READY;
|
|
current_state_ = WheelchairState::READY;
|
|
@@ -985,7 +1149,7 @@ void WorkflowManager::emergencyTransitionToReady(const std::string &reason)
|
|
|
state_publisher_->publish(msg);
|
|
state_publisher_->publish(msg);
|
|
|
|
|
|
|
|
// 如果之前是回充相关状态,发布回充失败
|
|
// 如果之前是回充相关状态,发布回充失败
|
|
|
- if (previous_state == "搜索中" || previous_state == "充电中")
|
|
|
|
|
|
|
+ if (previous_state == "搜索中" || previous_state == "充电中" || previous_state == "旋转中")
|
|
|
{
|
|
{
|
|
|
publishRechargeStatus("RECHARGE_EMERGENCY_FAILURE",
|
|
publishRechargeStatus("RECHARGE_EMERGENCY_FAILURE",
|
|
|
"系统异常导致回充紧急终止: " + reason);
|
|
"系统异常导致回充紧急终止: " + reason);
|
|
@@ -1075,13 +1239,53 @@ void WorkflowManager::stopSearchTimeoutTimer()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void WorkflowManager::searchTimeoutCallback()
|
|
|
|
|
|
|
+// ==================== 定时器回调 ====================
|
|
|
|
|
+
|
|
|
|
|
+void WorkflowManager::rotationCheckCallback()
|
|
|
{
|
|
{
|
|
|
try
|
|
try
|
|
|
{
|
|
{
|
|
|
if (current_state_ == WheelchairState::SEARCHING)
|
|
if (current_state_ == WheelchairState::SEARCHING)
|
|
|
{
|
|
{
|
|
|
- RCLCPP_WARN(node_->get_logger(), "搜索充电站超时30秒,回充失败");
|
|
|
|
|
|
|
+ checkRotationTransition();
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ RCLCPP_DEBUG(node_->get_logger(),
|
|
|
|
|
+ "旋转检查回调触发,但当前不在搜索状态");
|
|
|
|
|
+ stopRotationTimer();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (const std::exception &e)
|
|
|
|
|
+ {
|
|
|
|
|
+ handleException("旋转检查定时器回调", e);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void WorkflowManager::searchTimeoutCallback()
|
|
|
|
|
+{
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ if (current_state_ == WheelchairState::SEARCHING ||
|
|
|
|
|
+ current_state_ == WheelchairState::ROTATING)
|
|
|
|
|
+ {
|
|
|
|
|
+ double total_search_time = 0.0;
|
|
|
|
|
+
|
|
|
|
|
+ if (current_state_ == WheelchairState::SEARCHING)
|
|
|
|
|
+ {
|
|
|
|
|
+ total_search_time = (node_->now() - search_start_time_).seconds();
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (current_state_ == WheelchairState::ROTATING && rotation_manager_)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 计算总搜索时间:搜索时间 + 旋转时间
|
|
|
|
|
+ double search_duration = 10.0; // 搜索了10秒后才开始旋转
|
|
|
|
|
+ double rotation_duration = rotation_manager_->getRotationDuration();
|
|
|
|
|
+ total_search_time = search_duration + rotation_duration;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ RCLCPP_WARN(node_->get_logger(),
|
|
|
|
|
+ "总搜索时间 %.1f 秒超时(包括旋转),回充失败",
|
|
|
|
|
+ total_search_time);
|
|
|
handleSearchTimeoutEvent();
|
|
handleSearchTimeoutEvent();
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
@@ -1140,6 +1344,8 @@ std::string WorkflowManager::stateToString(WheelchairState state) const
|
|
|
return "就绪中";
|
|
return "就绪中";
|
|
|
case WheelchairState::WALKING:
|
|
case WheelchairState::WALKING:
|
|
|
return "行走中";
|
|
return "行走中";
|
|
|
|
|
+ case WheelchairState::ROTATING: // 新增
|
|
|
|
|
+ return "旋转中";
|
|
|
case WheelchairState::SEARCHING:
|
|
case WheelchairState::SEARCHING:
|
|
|
return "搜索中";
|
|
return "搜索中";
|
|
|
case WheelchairState::CHARGING:
|
|
case WheelchairState::CHARGING:
|