SimulatedHuman.cpp
Go to the documentation of this file.
1 /**
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @author Fabian Reister ( fabian dot reister at kit dot edu )
17  * @date 2022
18  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
19  * GNU General Public License
20  */
21 
22 #include "SimulatedHuman.h"
23 
24 #include <VirtualRobot/Random.h>
25 
27 
37 
39 {
40 
41 
44  {
45  switch (state_)
46  {
47  case State::Idle:
48  ARMARX_DEBUG << "State:Idle";
49  initialize();
50  state_ = State::Walking;
51  break;
52  case State::Walking:
53  {
54  ARMARX_DEBUG << "State:Walking";
55 
56  step();
57 
58  if (goalReached())
59  {
60  ARMARX_INFO << "Human reached goal";
61  state_ = State::GoalReached;
62  }
63 
64  break;
65  }
66  case State::GoalReached:
67  ARMARX_DEBUG << "State:GoalReached";
68 
69  // TODO(fabian.reister): simulate "perform action at goal": wait a while until movement is started again.
70  state_ = State::Idle;
71  break;
72  }
73 
74  return human_;
75  }
76 
77  bool
79  {
80  const Eigen::Vector2f goal =
81  conv::to2D(globalTrajectory_.points().back().waypoint.pose.translation());
82 
83  return ((goal - human_.pose.translation()).norm() < params_.goalDistanceThreshold);
84  }
85 
86  void
88  {
89  human_.pose = pose;
90 
91  if (goalReached())
92  {
93  ARMARX_VERBOSE << "Goal reached";
94  state_ = State::Idle;
95  }
96 
97  initialize();
98  update();
99  }
100 
101  void
103  {
105  params.linearVelocity = this->params_.maxLinearVelocity;
106  params.algo.obstacleDistanceWeight = 1.1F;
107 
108  core::Scene scene;
109 
110  scene.staticScene.emplace(core::StaticScene{nullptr, {}, {}, std::nullopt, {}});
111  scene.staticScene->distanceToObstaclesCostmap.emplace(distanceField_);
112 
113  global_planning::SPFA planner(params, scene);
114 
115  const core::Pose2D start = human_.pose;
116 
117  if (state_ == State::Idle) // human reached goal and needs a new one
118  {
119  while (true)
120  {
121  const auto sampledPose = algorithms::sampleValidPositionInMap(distanceField_);
122  ARMARX_CHECK(sampledPose.has_value());
123  const core::Pose2D& goal = sampledPose.value();
124 
125 
126  const auto plan = planner.plan(conv::to3D(start), conv::to3D(goal));
127 
128  // check if plan could be created. otherwise try another goal
129  if (plan.has_value())
130  {
131  globalTrajectory_ = plan->trajectory;
132 
133  human_ = human::Human{.pose = start,
134  .linearVelocity = Eigen::Vector2f::Zero(),
135  .detectionTime = Clock::Now()};
136  return;
137  }
138  }
139  }
140  else if (state_ == State::Walking) // human is walking and replans to existing goal
141  {
142  const auto goal = conv::to2D(globalTrajectory_.poses().back());
143  const auto plan = planner.plan(conv::to3D(start), conv::to3D(goal));
144 
145  // check if plan could be created. otherwise try another goal
146  if (plan.has_value())
147  {
148  globalTrajectory_ = plan->trajectory;
149 
150  human_ = human::Human{.pose = start,
151  .linearVelocity = Eigen::Vector2f::Zero(),
152  .detectionTime = Clock::Now()};
153  return;
154  }
155  }
156  }
157 
158  void
160  {
161  const auto updateTime = Clock::Now();
162 
163  const auto duration = updateTime - human_.detectionTime;
164 
165  // move according to old state
166  human_.pose.translation() += duration.toSecondsDouble() * human_.linearVelocity;
167 
168  const auto projection =
169  globalTrajectory_.getProjection(conv::to3D(human_.pose.translation()),
171 
172  human_.pose = conv::to2D(projection.projection.waypoint.pose);
173 
174  const auto wpBefore = projection.wayPointBefore.waypoint.pose.translation();
175  const auto wpAfter = projection.wayPointAfter.waypoint.pose.translation();
176 
177  human_.linearVelocity =
178  (wpAfter - wpBefore).head<2>().normalized() * projection.projection.velocity;
179 
180  human_.linearVelocity =
181  human_.linearVelocity.normalized() * std::clamp(human_.linearVelocity.norm(),
182  params_.minLinearVelocity,
183  params_.maxLinearVelocity);
184 
185  human_.detectionTime = updateTime;
186  }
187 
188  SimulatedHuman::SimulatedHuman(const algorithms::Costmap& distanceField, const Params& params) :
189  distanceField_(distanceField), params_(params)
190  {
191  const auto sampledPose = algorithms::sampleValidPositionInMap(distanceField_);
192  ARMARX_CHECK(sampledPose.has_value());
193  human_.pose = sampledPose.value();
194 
195  update(); // should bring the robot into walking state
196  }
197 } // namespace armarx::navigation::human::simulation
armarx::navigation::global_planning::SPFA
Definition: SPFA.h:69
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
SPFA.h
armarx::navigation::human::Human
Definition: types.h:33
armarx::navigation::core::Scene::staticScene
std::optional< core::StaticScene > staticScene
Definition: types.h:75
armarx::navigation::human::simulation::SimulatedHuman::step
void step()
Definition: SimulatedHuman.cpp:159
armarx::navigation::core::VelocityInterpolation::LinearInterpolation
@ LinearInterpolation
util.h
basic_types.h
armarx::navigation::algorithms::spfa::ShortestPathFasterAlgorithm::Parameters::obstacleDistanceWeight
float obstacleDistanceWeight
Definition: ShortestPathFasterAlgorithm.h:41
armarx::navigation::human::Human::pose
core::Pose2D pose
Definition: types.h:35
types.h
StaticScene.h
armarx::navigation::human::simulation::SimulatedHumanParams::goalDistanceThreshold
float goalDistanceThreshold
Definition: SimulatedHuman.h:34
armarx::navigation::human::simulation::SimulatedHuman::goalReached
bool goalReached() const
Definition: SimulatedHuman.cpp:78
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
clamp
double clamp(double x, double a, double b)
Definition: point.hpp:125
armarx::navigation::core::Pose2D
Eigen::Isometry2f Pose2D
Definition: basic_types.h:34
armarx::navigation::human::Human::detectionTime
DateTime detectionTime
Definition: types.h:37
ShortestPathFasterAlgorithm.h
Costmap.h
armarx::navigation::human::simulation::SimulatedHuman::reinitialize
void reinitialize(const core::Pose2D &pose)
resets the human to the given pose and replans the global optimal trajectory
Definition: SimulatedHuman.cpp:87
armarx::navigation::human::simulation::SimulatedHumanParams::minLinearVelocity
float minLinearVelocity
Definition: SimulatedHuman.h:36
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::navigation::human::simulation::SimulatedHuman::initialize
void initialize()
Definition: SimulatedHuman.cpp:102
armarx::navigation::human::simulation
This file is part of ArmarX.
Definition: SimulatedHuman.cpp:38
armarx::navigation::human::simulation::SimulatedHuman::SimulatedHuman
SimulatedHuman(const algorithms::Costmap &distanceField, const Params &params=Params())
Definition: SimulatedHuman.cpp:188
armarx::navigation::human::simulation::SimulatedHumanParams
Definition: SimulatedHuman.h:32
armarx::navigation::human::simulation::SimulatedHuman::State::GoalReached
@ GoalReached
armarx::navigation::core::GlobalTrajectory::poses
std::vector< Pose > poses() const noexcept
Definition: Trajectory.cpp:344
armarx::navigation::human::Human::linearVelocity
Eigen::Vector2f linearVelocity
Definition: types.h:36
armarx::navigation::global_planning::SPFAParams::algo
algorithms::spfa::ShortestPathFasterAlgorithm::Parameters algo
Definition: SPFA.h:53
armarx::navigation::core::Scene
Definition: types.h:71
armarx::navigation::human::simulation::SimulatedHuman::update
Human update()
Definition: SimulatedHuman.cpp:43
armarx::navigation::conv::to2D
std::vector< Eigen::Vector2f > to2D(const std::vector< Eigen::Vector3f > &v)
Definition: eigen.cpp:26
armarx::navigation::human::simulation::SimulatedHumanParams::maxLinearVelocity
float maxLinearVelocity
Definition: SimulatedHuman.h:37
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::navigation::algorithms::sampleValidPositionInMap
std::optional< core::Pose2D > sampleValidPositionInMap(const algorithms::Costmap &costmap)
Definition: util.cpp:368
armarx::navigation::global_planning::SPFAParams::linearVelocity
float linearVelocity
Definition: SPFA.h:43
armarx::navigation::conv::to3D
std::vector< Eigen::Vector3f > to3D(const std::vector< Eigen::Vector2f > &v)
Definition: eigen.cpp:11
armarx::navigation::human::simulation::SimulatedHuman::State::Idle
@ Idle
armarx::core::time::Clock::Now
static DateTime Now()
Current time on the virtual clock.
Definition: Clock.cpp:97
SimulatedHuman.h
armarx::navigation::global_planning::SPFA::plan
std::optional< GlobalPlannerResult > plan(const core::Pose &goal) override
Definition: SPFA.cpp:82
armarx::navigation::core::GlobalTrajectory::getProjection
Projection getProjection(const Position &point, const VelocityInterpolation &velocityInterpolation) const
Definition: Trajectory.cpp:243
eigen.h
Logging.h
armarx::navigation::core::StaticScene
Definition: StaticScene.h:40
armarx::navigation::human::simulation::SimulatedHuman::State::Walking
@ Walking
armarx::navigation::core::GlobalTrajectory::points
const std::vector< GlobalTrajectoryPoint > & points() const
Definition: Trajectory.cpp:732
types.h
armarx::navigation::global_planning::SPFAParams
Parameters for AStar.
Definition: SPFA.h:41
armarx::navigation::algorithms::Costmap
Definition: Costmap.h:13