10 #include <boost/smart_ptr/make_shared_object.hpp>
12 #include <SimoxUtility/algorithm/apply.hpp>
13 #include <SimoxUtility/color/Color.h>
14 #include <VirtualRobot/CollisionDetection/CollisionModel.h>
15 #include <VirtualRobot/Robot.h>
16 #include <VirtualRobot/SceneObjectSet.h>
34 #include <armarx/navigation/local_planning/aron/TimedElasticBands.aron.generated.h>
39 #include <geometry_msgs/Twist.h>
40 #include <nlohmann/json_fwd.hpp>
42 #include <teb_local_planner/homotopy_class_planner.h>
43 #include <teb_local_planner/pose_se2.h>
44 #include <teb_local_planner/robot_footprint_model.h>
45 #include <teb_local_planner/timed_elastic_band.h>
46 #include <teb_local_planner/visualization.h>
54 LocalPlanner(scene), params(i_params), scene(scene), obstManager(teb_obstacles)
57 const auto robotName = scene.
robot->getName();
64 auto robot_model = boost::make_shared<teb_local_planner::CircularRobotFootprint>(
69 hcp_ = std::make_unique<teb_local_planner::HomotopyClassPlanner>();
71 cfg_, &teb_obstacles, robot_model, teb_local_planner::TebVisualizationPtr(),
nullptr);
82 hcp_->setCostmap(&teb_costmap.value());
88 TimedElasticBands::readConfig(arondto::TimedElasticBandsParams&
target,
89 const std::string& robotName)
96 "local_planner_config/TimedElasticBands/" + robotName +
".json");
98 if (std::filesystem::exists(robotSpecificConfigPath.toSystemPath()))
100 ARMARX_INFO <<
"Using robot-specific config `" << robotSpecificConfigPath <<
"`.";
101 return robotSpecificConfigPath;
105 "armarx_navigation",
"local_planner_config/TimedElasticBands/default.json");
106 ARMARX_INFO <<
"Using default config `" << robotSpecificConfigPath <<
"`";
108 return defaultConfigPath;
111 const std::filesystem::path file = configPath.
toSystemPath();
113 ARMARX_CHECK(std::filesystem::is_regular_file(file)) << file;
115 ARMARX_INFO <<
"Loading config from file `" << file <<
"`.";
116 std::ifstream ifs{file};
118 nlohmann::json jsonConfig;
124 target.read(reader, jsonConfig);
127 std::optional<LocalPlannerResult>
134 currentPose.translation(),
params.
cfg.planning_distance * 1000);
136 const teb_local_planner::TimedElasticBand globalPath =
conv::toRos(prunedGoal);
137 teb_globalPath = globalPath.poses();
138 hcp_->setGlobalPath(&teb_globalPath);
140 const teb_local_planner::PoseSE2 start =
conv::toRos(currentPose);
141 const teb_local_planner::PoseSE2 end =
142 conv::toRos(prunedGoal.points().back().waypoint.pose);
152 success = hcp_->plan(start, end, &velocity_start, !planToDest);
156 hcp_->clearPlanner();
166 ARMARX_INFO <<
"Found trajectory is not feasible!";
167 hcp_->clearPlanner();
172 if (
false && hcp_->hasDiverged())
175 hcp_->clearPlanner();
180 if (hcp_->getTrajectoryContainer().empty())
182 hcp_->clearPlanner();
187 ARMARX_VERBOSE <<
"Planned successfully (found " << hcp_->getTrajectoryContainer().size()
195 auto layer =
arviz.value().layer(
"local_planner_path_alternatives");
198 int bestTebIdx = hcp_->bestTebIdx();
199 for (
const auto& teb : hcp_->getTrajectoryContainer())
206 const std::vector<Eigen::Vector3f> points =
207 simox::alg::apply(trajectory.
points(),
209 { return pt.pose.translation(); });
212 .color(simox::Color::gray()));
216 arviz.value().commit(layer);
219 return {{.trajectory = best}};
223 TimedElasticBands::fillObstacles()
231 visLayer =
arviz.value().layer(
"local_planner_obstacles");
239 for (
const auto& obst : scene.
staticScene.value().objects->getCollisionModels())
247 for (
const auto& obst : scene.
dynamicScene.value().humans)
252 for (
const auto& obst : scene.
dynamicScene->laserScannerFeatures)
260 arviz.value().commit(visLayer);
268 TimedElasticBands::setTebCostmap()
275 if (not scene.
staticScene->distanceToObstaclesCostmap.has_value())
282 const algorithms::Costmap& navigationCostmap =
283 scene.
staticScene->distanceToObstaclesCostmap.value();
284 teb_costmap.emplace(
conv::toRos(navigationCostmap));