// // Created by tlab-uav on 24-9-24. // #include "Ocs2QuadrupedController.h" #include #include #include #include #include #include #include #include namespace ocs2::legged_robot { controller_interface::CallbackReturn Ocs2QuadrupedController::on_init() { verbose_ = false; loadData::loadCppDataType(task_file_, "legged_robot_interface.verbose", verbose_); setUpLeggedInterface(); setupMpc(); setupMrt(); // Visualization CentroidalModelPinocchioMapping pinocchioMapping(legged_interface_->getCentroidalModelInfo()); eeKinematicsPtr_ = std::make_shared( legged_interface_->getPinocchioInterface(), pinocchioMapping, legged_interface_->modelSettings().contactNames3DoF); // robotVisualizer_ = std::make_shared(leggedInterface_->getPinocchioInterface(), // leggedInterface_->getCentroidalModelInfo(), *eeKinematicsPtr_, nh); // selfCollisionVisualization_.reset(new LeggedSelfCollisionVisualization(leggedInterface_->getPinocchioInterface(), // leggedInterface_->getGeometryInterface(), pinocchioMapping, nh)); // State estimation setupStateEstimate(); // Whole body control wbc_ = std::make_shared(legged_interface_->getPinocchioInterface(), legged_interface_->getCentroidalModelInfo(), *eeKinematicsPtr_); wbc_->loadTasksSetting(task_file_, verbose_); // Safety Checker safetyChecker_ = std::make_shared(legged_interface_->getCentroidalModelInfo()); return CallbackReturn::SUCCESS; } void Ocs2QuadrupedController::setUpLeggedInterface() { legged_interface_ = std::make_shared(task_file_, urdf_file_, reference_file_); legged_interface_->setupOptimalControlProblem(task_file_, urdf_file_, reference_file_, verbose_); } void Ocs2QuadrupedController::setupMpc() { mpc_ = std::make_shared(legged_interface_->mpcSettings(), legged_interface_->sqpSettings(), legged_interface_->getOptimalControlProblem(), legged_interface_->getInitializer()); rbdConversions_ = std::make_shared(legged_interface_->getPinocchioInterface(), legged_interface_->getCentroidalModelInfo()); const std::string robotName = "legged_robot"; // Gait receiver auto gaitReceiverPtr = std::make_shared(this->get_node(), legged_interface_->getSwitchedModelReferenceManagerPtr()-> getGaitSchedule(), robotName); // ROS ReferenceManager auto rosReferenceManagerPtr = std::make_shared( robotName, legged_interface_->getReferenceManagerPtr()); rosReferenceManagerPtr->subscribe(this->get_node()); mpc_->getSolverPtr()->addSynchronizedModule(gaitReceiverPtr); mpc_->getSolverPtr()->setReferenceManager(rosReferenceManagerPtr); observationPublisher_ = nh.advertise(robotName + "_mpc_observation", 1); } void Ocs2QuadrupedController::setupMrt() { mpcMrtInterface_ = std::make_shared(*mpc_); mpcMrtInterface_->initRollout(&legged_interface_->getRollout()); mpcTimer_.reset(); controllerRunning_ = true; mpcThread_ = std::thread([&]() { while (controllerRunning_) { try { executeAndSleep( [&]() { if (mpcRunning_) { mpcTimer_.startTimer(); mpcMrtInterface_->advanceMpc(); mpcTimer_.endTimer(); } }, legged_interface_->mpcSettings().mpcDesiredFrequency_); } catch (const std::exception &e) { controllerRunning_ = false; RCLCPP_WARN(get_node()->get_logger(), "[Ocs2 MPC thread] Error : %s", e.what()); } } }); setThreadPriority(legged_interface_->sqpSettings().threadPriority, mpcThread_); } void Ocs2QuadrupedController::setupStateEstimate() { stateEstimate_ = std::make_shared(legged_interface_->getPinocchioInterface(), legged_interface_->getCentroidalModelInfo(), *eeKinematicsPtr_, this->get_node()); dynamic_cast(*stateEstimate_).loadSettings(task_file_, verbose_); currentObservation_.time = 0; } }