CARLA
 
载入中...
搜索中...
未找到
Episode.cpp
浏览该文件的文档.
1// Copyright (c) 2017 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// 包含Carla项目中客户端相关的Episode(场景、情节相关概念,可能代表一次模拟过程等)的头文件,
7// 推测其中定义了Episode类的声明等内容,用于处理模拟场景相关的操作和状态管理
9
10#include "carla/Logging.h"
15
16#include <exception>
17
18namespace carla {
19namespace client {
20namespace detail {
21// 使用命名空间中的chrono_literals,用于方便地表示时间常量
22using namespace std::chrono_literals;
23// 静态函数,将传感器数据强制转换为特定类型
24 static auto &CastData(const sensor::SensorData &data) {
25 using target_t = const sensor::data::RawEpisodeState;
26 return static_cast<target_t &>(data);
27 }
28// 模板函数,根据给定的参与者ID范围获取演员列表
29 template <typename RangeT>
30 static auto GetActorsById_Impl(Client &client, CachedActorList &actors, const RangeT &actor_ids) {
31 // 获取缺失的参与者ID
32 auto missing_ids = actors.GetMissingIds(actor_ids);
33 if (!missing_ids.empty()) {
34 // 如果有缺失的ID,从客户端获取对应参与者并插入列表
35 actors.InsertRange(client.GetActorsById(missing_ids));
36 }
37 // 返回指定ID的参与者列表
38 return actors.GetActorsById(actor_ids);
39 }
40// 构造函数,通过客户端和弱引用的模拟器创建Episode对象,并使用默认的EpisodeInfo
41 Episode::Episode(Client &client, std::weak_ptr<Simulator> simulator)
42 : Episode(client, client.GetEpisodeInfo(), simulator) {}
43// 构造函数,通过客户端、EpisodeInfo和弱引用的模拟器创建Episode对象
44 Episode::Episode(Client &client, const rpc::EpisodeInfo &info, std::weak_ptr<Simulator> simulator)
45 : _client(client),
46 _state(std::make_shared<EpisodeState>(info.id)),
47 _simulator(simulator),
48 _token(info.token) {}
49// 析构函数,尝试取消订阅流并处理可能的异常
51 try {
53 } catch (const std::exception &e) {
54 log_error("exception trying to disconnect from episode:", e.what());
55 }
56 }
57// 开始监听流数据的函数
59 std::weak_ptr<Episode> weak = shared_from_this();
60 _client.SubscribeToStream(_token, [weak](auto buffer) {
61 auto self = weak.lock();
62 if (self != nullptr) {
63 // 反序列化数据
64 auto data = sensor::Deserializer::Deserialize(std::move(buffer));
65 auto next = std::make_shared<const EpisodeState>(CastData(*data));
66 auto prev = self->GetState();
67
68 // TODO: 更新地图变化的检测方式
69 bool HasMapChanged = next->HasMapChanged();
70 bool UpdateLights = next->IsLightUpdatePending();
71
72 /// 检查待处理的异常(主要是交通管理服务器关闭)
73 if(self->_pending_exceptions) {
74
75 /// 将待处理的异常标记为 false
76 self->_pending_exceptions = false;
77
78 /// 为错误消息创建异常
79 auto exception(self->_pending_exceptions_msg);
80 // 通知等待线程发生异常
81 self->_snapshot.SetException(std::runtime_error(exception));
82 }
83 /// 传感器案例:数据不一致
84 else {
85 bool episode_changed = (next->GetEpisodeId() != prev->GetEpisodeId());
86
87 do {// 如果当前状态的帧编号(GetFrame函数获取)大于等于下一个状态的帧编号,并且模拟场景没有改变(episode_changed为false),
88 // 则调用_on_tick_callbacks(可能是一个用于存储和执行每帧回调函数的对象)的Call函数,传入下一个状态数据,然后直接返回,
89 // 表示这种情况下已经处理完当前数据,不需要进行后续的状态更新等操作。
90 if (prev->GetFrame() >= next->GetFrame() && !episode_changed) {
91 self->_on_tick_callbacks.Call(next);
92 return;
93 }
94 } while (!self->_state.compare_exchange(&prev, next));
95// 如果需要更新交通信号灯(UpdateLights为true)或者地图发生了变化(HasMapChanged为true),
96 // 则调用_on_light_update_callbacks(可能是一个用于处理交通信号灯更新相关回调函数的对象)的Call函数,传入下一个状态数据。
97 if(UpdateLights || HasMapChanged) {
98 self->_on_light_update_callbacks.Call(next);
99 }
100// 如果地图发生了变化,将_should_update_map标记为true,表示需要在后续的操作中更新地图相关的内容。
101 if(HasMapChanged) {
102 self->_should_update_map = true;
103 }
104
105 /// Episode 改变
106 if(episode_changed) {
107 self->OnEpisodeChanged();
108 }
109
110 // 通知等待的线程并执行回调。
111 self->_snapshot.SetValue(next);
112/ 通知等待的线程并执行回调,通过调用_snapshot的SetValue函数,传入下一个状态数据,
113 // 这样其他等待该状态数据的部分(可能是其他线程或者模块)就可以获取到最新的状态并进行相应操作。
114 // 同时调用_on_tick_callbacks的Call函数,传入下一个状态数据,执行用户注册的每帧回调函数。
115
116 self->_on_tick_callbacks.Call(next);
117 }
118 }
119 });
120 }
121// Episode类的成员函数GetActorById,用于根据给定的参与者ID获取单个参与者信息。
122 // 首先尝试从缓存的参与者列表_actors中获取对应的参与者信息(通过调用GetActorById函数),如果获取不到(返回的结果没有值),
123 // 则从客户端获取该ID对应的参与者信息列表(通过调用_client的GetActorsById函数传入单个ID的列表),
124 // 如果获取到的列表不为空,则取出第一个参与者信息(假设ID是唯一对应的),并插入到缓存列表_actors中,最后返回获取到的参与者信息(如果有的话)
125 boost::optional<rpc::Actor> Episode::GetActorById(ActorId id) {
126 auto actor = _actors.GetActorById(id);
127 if (!actor.has_value()) {
128 auto actor_list = _client.GetActorsById({id});
129 if (!actor_list.empty()) {
130 actor = std::move(actor_list.front());
131 _actors.Insert(*actor);
132 }
133 }
134 return actor;
135 }
136// Episode类的成员函数GetActorsById,用于根据给定的参与者ID列表获取对应的参与者列表。
137 // 它调用了前面定义的模板函数GetActorsById_Impl,传入客户端对象、缓存的参与者列表对象以及给定的参与者ID列表,
138 // 通过模板函数内部的逻辑来获取并返回对应的参与者列表(如果有的话),可能涉及从缓存中获取或者从客户端获取缺失的参与者信息等操作。
139 std::vector<rpc::Actor> Episode::GetActorsById(const std::vector<ActorId> &actor_ids) {
140 return GetActorsById_Impl(_client, _actors, actor_ids);
141 }
142// Episode类的成员函数GetActors,用于获取所有的参与者列表。
143 // 它同样调用了模板函数GetActorsById_Impl,不过传入的参与者ID范围是通过调用GetState函数获取当前模拟场景状态中的所有参与者ID列表,
144 // 以此来获取并返回整个模拟场景中的所有参与者信息列表(如果有的话)。
145 std::vector<rpc::Actor> Episode::GetActors() {
146 return GetActorsById_Impl(_client, _actors, GetState()->GetActorIds());
147 }
148// Episode类的成员函数OnEpisodeStarted,用于在模拟场景(Episode)开始时执行一些初始化和清理操作。
149 // 它会清空缓存的参与者列表_actors,清除每帧回调函数列表_on_tick_callbacks,重置行人导航对象_walker_navigation(如果有的话),
150 // 以及调用交通管理模块(TrafficManager)的Release函数(可能用于释放之前的资源或者重置相关状态等操作)。
157// Episode类的成员函数OnEpisodeChanged,用于在模拟场景(Episode)发生改变(比如场景切换、重新初始化等情况)时执行相应的操作。
158 // 这里调用了交通管理模块(TrafficManager)的Reset函数,可能用于重置交通管理相关的状态、参数等内容,以适应新的模拟场景情况。
162// Episode类的成员函数HasMapChangedSinceLastCall,用于检查自上次调用该函数以来地图是否发生了变化。
163 // 通过检查_should_update_map成员变量(如果为true表示地图需要更新,即发生了变化),如果为true则将其重置为false并返回true,
164 // 表示地图发生了变化;如果为false则直接返回false,表示地图没有发生变化。
167 _should_update_map = false;
168 return true;
169 }
170 return false;
171 }// Episode类的成员函数CreateNavigationIfMissing,用于创建一个WalkerNavigation对象(行人导航对象),如果该对象还不存在的话。
172 // 通过一个循环和原子操作compare_exchange来确保只有一个线程能够成功创建新的WalkerNavigation对象(如果当前不存在的话),
173 // 一旦创建成功或者已经存在,则返回指向该WalkerNavigation对象的共享指针。
174 std::shared_ptr<WalkerNavigation> Episode::CreateNavigationIfMissing() {
175 std::shared_ptr<WalkerNavigation> nav;
176 do {
177 nav = _walker_navigation.load();
178 if (nav == nullptr) {
179 auto new_nav = std::make_shared<WalkerNavigation>(_simulator);
180 _walker_navigation.compare_exchange(&nav, new_nav);
181 }
182 } while (nav == nullptr);
183 return nav;
184 }
185
186} // namespace detail
187} // namespace client
188} // namespace carla
保留参与者描述列表,以避免每次都向服务器请求描述。
boost::optional< rpc::Actor > GetActorById(ActorId id) const
检索与 id 匹配的参与者,如果参与者未被缓存,则为空(可选)。
void InsertRange(RangeT range)
插入包含参与者的 范围。
void Insert(rpc::Actor actor)
将参与者插入到列表中。
std::vector< rpc::Actor > GetActorsById(const RangeT &range) const
检索与 范围内的 ID 匹配的参与者。
std::vector< ActorId > GetMissingIds(const RangeT &range) const
返回 范围内尚未添加到此列表的参与者 ID。
提供与 CARLA 模拟器的 rpc 和流媒体服务器的通信。
std::vector< rpc::Actor > GetActorsById(const std::vector< ActorId > &ids)
void UnSubscribeFromStream(const streaming::Token &token)
void SubscribeToStream(const streaming::Token &token, std::function< void(Buffer)> callback)
表示某一帧的所有参与者的状态
持有当前剧集及当前剧集状态
Definition Episode.h:35
std::weak_ptr< Simulator > _simulator
Definition Episode.h:135
CallbackList< WorldSnapshot > _on_tick_callbacks
Definition Episode.h:119
std::shared_ptr< WalkerNavigation > CreateNavigationIfMissing()
Definition Episode.cpp:174
std::shared_ptr< const EpisodeState > GetState() const
Definition Episode.h:48
const streaming::Token _token
Definition Episode.h:129
AtomicSharedPtr< WalkerNavigation > _walker_navigation
Definition Episode.h:127
Episode(Client &client, std::weak_ptr< Simulator > simulator)
Definition Episode.cpp:41
static SharedPtr< SensorData > Deserialize(Buffer &&buffer)
静态函数,用于执行反序列化操作。
所有传感器生成数据的对象的基类
Definition SensorData.h:22
表示给定帧处剧集的状态。
static void Release()
释放TrafficManager对象,用于单例模式的清理工作
static void Reset()
重置TrafficManager对象,用于单例模式的重置操作
static auto GetActorsById_Impl(Client &client, CachedActorList &actors, const RangeT &actor_ids)
Definition Episode.cpp:30
static auto & CastData(const sensor::SensorData &data)
Definition Episode.cpp:24
carla::ActorId ActorId
参与者的智能指针类型
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
static void log_error(Args &&... args)
Definition Logging.h:115
包含CARLA客户端相关类和函数的命名空间。