CARLA
WalkerNavigation.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
2 // de Barcelona (UAB).
3 //
4 // This work is licensed under the terms of the MIT license.
5 // For a copy, see <https://opensource.org/licenses/MIT>.
6 
8 
13 #include "carla/nav/Navigation.h"
14 #include "carla/rpc/Command.h"
15 #include "carla/rpc/DebugShape.h"
17 
18 #include <sstream>
19 
20 namespace carla {
21 namespace client {
22 namespace detail {
23 
24  WalkerNavigation::WalkerNavigation(std::weak_ptr<Simulator> simulator) : _simulator(simulator), _next_check_index(0) {
25  _nav.SetSimulator(simulator);
26  // Here call the server to retrieve the navmesh data.
27  auto files = _simulator.lock()->GetRequiredFiles("Nav");
28  if (!files.empty()) {
29  _nav.Load(_simulator.lock()->GetCacheFile(files[0], true));
30  }
31  }
32 
33  void WalkerNavigation::Tick(std::shared_ptr<Episode> episode) {
34  auto walkers = _walkers.Load();
35  if (walkers->empty()) {
36  return;
37  }
38 
39  // get current state
40  std::shared_ptr<const EpisodeState> state = episode->GetState();
41 
42  // purge all possible dead walkers
43  CheckIfWalkerExist(*walkers, *state);
44 
45  // add/update/delete all vehicles in crowd
46  UpdateVehiclesInCrowd(episode, false);
47 
48  // update crowd in navigation module
49  _nav.UpdateCrowd(*state);
50 
52  using Cmd = rpc::Command;
53  std::vector<Cmd> commands;
54  commands.reserve(walkers->size());
55  for (auto handle : *walkers) {
56  // get the transform of the walker
57  if (_nav.GetWalkerTransform(handle.walker, trans)) {
58  float speed = _nav.GetWalkerSpeed(handle.walker);
59  commands.emplace_back(Cmd::ApplyWalkerState{ handle.walker, trans, speed });
60  }
61  }
62  _simulator.lock()->ApplyBatchSync(std::move(commands), false);
63 
64  // check if any agent has been killed
65  bool alive;
66  for (auto handle : *walkers) {
67  // get the agent state
68  if (_nav.IsWalkerAlive(handle.walker, alive)) {
69  if (!alive) {
70  _simulator.lock()->SetActorCollisions(handle.walker, true);
71  _simulator.lock()->SetActorDead(handle.walker);
72  // remove from the crowd
73  _nav.RemoveAgent(handle.walker);
74  // destroy the controller
75  _simulator.lock()->DestroyActor(handle.controller);
76  // unregister from list
77  UnregisterWalker(handle.walker, handle.controller);
78  }
79  }
80  }
81  }
82 
83  void WalkerNavigation::CheckIfWalkerExist(std::vector<WalkerHandle> walkers, const EpisodeState &state) {
84 
85  // check with total
86  if (_next_check_index >= walkers.size())
88 
89  // check the existence
90  if (!state.ContainsActorSnapshot(walkers[_next_check_index].walker)) {
91  // remove from the crowd
92  _nav.RemoveAgent(walkers[_next_check_index].walker);
93  // destroy the controller
94  _simulator.lock()->DestroyActor(walkers[_next_check_index].controller);
95  // unregister from list
96  UnregisterWalker(walkers[_next_check_index].walker, walkers[_next_check_index].controller);
97  }
98 
100 
101  }
102 
103  // add/update/delete all vehicles in crowd
104  void WalkerNavigation::UpdateVehiclesInCrowd(std::shared_ptr<Episode> episode, bool show_debug) {
105  std::vector<carla::nav::VehicleCollisionInfo> vehicles;
106 
107  // get current state
108  std::shared_ptr<const EpisodeState> state = episode->GetState();
109 
110  // get all vehicles from episode
111  for (auto &&actor : episode->GetActors()) {
112  // only vehicles
113  if (actor.description.id.rfind("vehicle.", 0) == 0) {
114  // get the snapshot
115  ActorSnapshot snapshot = state->GetActorSnapshot(actor.id);
116  // add to the vector
117  vehicles.emplace_back(carla::nav::VehicleCollisionInfo{actor.id, snapshot.transform, actor.bounding_box});
118  }
119  }
120 
121  // update the vehicles found
122  _nav.UpdateVehicles(vehicles);
123 
124  // optional debug info
125  if (show_debug) {
126  if (_nav.GetCrowd() == nullptr) return;
127 
128  // draw bounding boxes for debug
129  for (int i = 0; i < _nav.GetCrowd()->getAgentCount(); ++i) {
130  // get the agent
131  const dtCrowdAgent *agent = _nav.GetCrowd()->getAgent(i);
132  if (agent && agent->params.useObb) {
133  // draw for debug
134  carla::geom::Location p1, p2, p3, p4;
135  p1.x = agent->params.obb[0];
136  p1.z = agent->params.obb[1];
137  p1.y = agent->params.obb[2];
138  p2.x = agent->params.obb[3];
139  p2.z = agent->params.obb[4];
140  p2.y = agent->params.obb[5];
141  p3.x = agent->params.obb[6];
142  p3.z = agent->params.obb[7];
143  p3.y = agent->params.obb[8];
144  p4.x = agent->params.obb[9];
145  p4.z = agent->params.obb[10];
146  p4.y = agent->params.obb[11];
148  line1.life_time = 0.01f;
149  line1.persistent_lines = false;
150  // line 1
151  line1.primitive = carla::rpc::DebugShape::Line {p1, p2, 0.2f};
152  line1.color = { 0, 255, 0 };
153  _simulator.lock()->DrawDebugShape(line1);
154  // line 2
155  line1.primitive = carla::rpc::DebugShape::Line {p2, p3, 0.2f};
156  line1.color = { 255, 0, 0 };
157  _simulator.lock()->DrawDebugShape(line1);
158  // line 3
159  line1.primitive = carla::rpc::DebugShape::Line {p3, p4, 0.2f};
160  line1.color = { 0, 0, 255 };
161  _simulator.lock()->DrawDebugShape(line1);
162  // line 4
163  line1.primitive = carla::rpc::DebugShape::Line {p4, p1, 0.2f};
164  line1.color = { 255, 255, 0 };
165  _simulator.lock()->DrawDebugShape(line1);
166  }
167  }
168 
169  // draw some text for debug
170  for (int i = 0; i < _nav.GetCrowd()->getAgentCount(); ++i) {
171  // get the agent
172  const dtCrowdAgent *agent = _nav.GetCrowd()->getAgent(i);
173  if (agent) {
174  // draw for debug
175  carla::geom::Location p1(agent->npos[0], agent->npos[2], agent->npos[1] + 1);
176  if (agent->params.userData) {
177  std::ostringstream out;
178  out << *(reinterpret_cast<const float *>(agent->params.userData));
180  text.life_time = 0.01f;
181  text.persistent_lines = false;
182  text.primitive = carla::rpc::DebugShape::String {p1, out.str(), false};
183  text.color = { 0, 255, 0 };
184  _simulator.lock()->DrawDebugShape(text);
185  }
186  }
187  }
188  }
189  }
190 
191 } // namespace detail
192 } // namespace client
193 } // namespace carla
void SetSimulator(std::weak_ptr< carla::client::detail::Simulator > simulator)
reference to the simulator to access API functions
Definition: Navigation.cpp:71
void CheckIfWalkerExist(std::vector< WalkerHandle > walkers, const EpisodeState &state)
check a few walkers and if they don&#39;t exist then remove from the crowd
WalkerNavigation(std::weak_ptr< Simulator > simulator)
bool RemoveAgent(ActorId id)
remove an agent
Definition: Navigation.cpp:663
carla::rpc::ActorId id
Definition: Navigation.h:48
This file contains definitions of common data structures used in traffic manager. ...
Definition: Carla.cpp:133
Represents the state of all the actors of an episode at a given frame.
Definition: EpisodeState.h:27
dtCrowd * GetCrowd()
Definition: Navigation.h:116
bool ContainsActorSnapshot(ActorId actor_id) const
Definition: EpisodeState.h:63
void UpdateVehiclesInCrowd(std::shared_ptr< Episode > episode, bool show_debug=false)
add/update/delete all vehicles in crowd
void UpdateCrowd(const client::detail::EpisodeState &state)
update all walkers in crowd
Definition: Navigation.cpp:834
void Tick(std::shared_ptr< Episode > episode)
bool GetWalkerTransform(ActorId id, carla::geom::Transform &trans)
get the walker current transform
Definition: Navigation.cpp:923
void UnregisterWalker(ActorId walker_id, ActorId controller_id)
float GetWalkerSpeed(ActorId id)
get the walker current transform
struct to send info about vehicles to the crowd
Definition: Navigation.h:47
bool IsWalkerAlive(ActorId id, bool &alive)
return if the agent has been killed by a vehicle
std::weak_ptr< Simulator > _simulator
boost::variant2::variant< Point, Line, Arrow, Box, String > primitive
Definition: DebugShape.h:65
bool Load(const std::string &filename)
load navigation data
Definition: Navigation.cpp:83
bool UpdateVehicles(std::vector< VehicleCollisionInfo > vehicles)
add/update/delete vehicles in crowd
Definition: Navigation.cpp:709