CARLA
 
载入中...
搜索中...
未找到
primaryCommands.cpp
浏览该文件的文档.
1// Copyright (c) 2022 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
9// #include "carla/Logging.h"
10// #include "carla/Logging.h" // 用于日志记录(目前未启用)
17
18namespace carla {
19namespace multigpu {
20
21// PrimaryCommands类的默认构造函数,目前为空实现,可能后续用于对象的默认初始化等情况
24
25// PrimaryCommands类的构造函数,接受一个指向Router的智能指针作为参数,用于初始化成员变量_router
26// 参数router: 指向Router对象的智能指针,用于后续的消息路由等操作
27PrimaryCommands::PrimaryCommands(std::shared_ptr<Router> router) :
28 _router(router) {
29}
30
31// 设置路由器(Router)的函数,用于更新当前PrimaryCommands对象所使用的路由器
32// 参数router: 新的指向Router对象的智能指针
33void PrimaryCommands::set_router(std::shared_ptr<Router> router) {
34 _router = router;
35}
36
37// 向所有辅助服务器广播帧数据的函数
38// 参数buffer: 包含帧数据的carla::Buffer类型对象,会将此数据通过路由器发送给所有辅助服务器
39// 实现方式是调用_router的Write方法,传递对应的命令类型(MultiGPUCommand::SEND_FRAME)和要发送的数据(移动语义传递buffer)
41 _router->Write(MultiGPUCommand::SEND_FRAME, std::move(buffer));
42 // log_info("sending frame command"); // 此处原代码有日志输出,可能用于调试等记录发送帧命令的操作,当前被注释掉了
43}
44
45// 向所有辅助服务器广播要加载的地图的函数
46// 参数map: 表示地图名称的字符串,先将其转换为carla::Buffer类型,再通过路由器发送给所有辅助服务器
47// 转换为Buffer时,会包含字符串内容以及结尾的'\0'字符(通过 + 1 来保证包含结尾字符),然后调用_router的Write方法发送,命令类型为MultiGPUCommand::LOAD_MAP
48void PrimaryCommands::SendLoadMap(std::string map) {
49 carla::Buffer buf((unsigned char *) map.c_str(), (size_t) map.size() + 1);
50 // 使用 _router->Write() 方法将地图加载命令广播给所有辅助服务器,命令类型为 MultiGPUCommand::LOAD_MAP
51 _router->Write(MultiGPUCommand::LOAD_MAP, std::move(buf));
52}
53
54// 向路由器需要令牌的人员发送请求的函数,用于获取令牌(token)
55// 参数sensor_id: 传感器的ID,用于标识请求令牌对应的传感器
56// 函数先记录请求令牌的日志信息(log_info),然后将sensor_id放入carla::Buffer中,通过路由器的WriteToNext方法异步发送请求(命令类型为MultiGPUCommand::GET_TOKEN)
57// 接着等待异步操作完成(fut.get())获取响应,从响应中解析出新的令牌(token_type),并记录获取到的令牌信息,最后返回该令牌
59 // 记录请求令牌的日志信息
60 log_info("asking for a token");
61 // 将 sensor_id 放入 carla::Buffer 中
63 (size_t) sizeof(stream_id));
64 // 使用 _router->WriteToNext() 异步向下游发送请求,命令类型为 MultiGPUCommand::GET_TOKEN
65 auto fut = _router->WriteToNext(MultiGPUCommand::GET_TOKEN, std::move(buf));
66// 阻塞当前线程,等待异步响应完成
67 auto response = fut.get();
68 // 记录令牌信息
69 token_type new_token(*reinterpret_cast<carla::streaming::detail::token_data *>(response.buffer.data()));
70 log_info("got a token: ", new_token.get_stream_id(), ", ", new_token.get_port());
71 return new_token;
72}
73
74// 发送以了解连接是否处于活动状态的函数
75// 先构造一个简单的询问消息字符串,将其转换为carla::Buffer类型,记录发送命令的日志信息(log_info),然后通过路由器的WriteToNext方法异步发送(命令类型为MultiGPUCommand::YOU_ALIVE)
76// 等待异步操作完成获取响应,并记录响应内容的日志信息(log_info)
78 std::string msg("Are you alive?");
79 carla::Buffer buf((unsigned char *) msg.c_str(), (size_t) msg.size());
80 log_info("sending is alive command");
81 // 使用 _router->WriteToNext() 异步向下游发送该命令,命令类型为 MultiGPUCommand::YOU_ALIVE
82 auto fut = _router->WriteToNext(MultiGPUCommand::YOU_ALIVE, std::move(buf));
83 // 等待异步操作完成,获取响应并记录日志
84 auto response = fut.get();
85 log_info("response from alive command: ", response.buffer.data());
86}
87
88// 发送启用ROS相关功能的命令给特定传感器所在的辅助服务器(如果传感器已在某辅助服务器中激活)
89// 参数sensor_id: 传感器的ID,用于查找对应的辅助服务器
90// 首先在已记录的服务器列表(_servers)中查找该传感器是否已在某个辅助服务器中激活,如果找到:
91// - 将sensor_id放入carla::Buffer中,通过路由器的WriteToOne方法异步发送启用命令(命令类型为MultiGPUCommand::ENABLE_ROS)给对应的服务器
92// - 等待异步操作完成获取响应,并从响应中解析出布尔值结果(表示启用操作是否成功等情况)
93// 如果没找到对应的服务器,记录错误日志,表示该传感器在任何服务器上都没找到
95 // 搜索传感器是否已在任何辅助服务器中激活
96 auto it = _servers.find(sensor_id);
97 if (it!= _servers.end()) {
98 // 如果找到传感器,封装 sensor_id 成 carla::Buffer
100 (size_t) sizeof(stream_id));
101 // 使用 _router->WriteToOne() 向目标服务器发送启用 ROS 命令,命令类型为 MultiGPUCommand::ENABLE_ROS
102 auto fut = _router->WriteToOne(it->second, MultiGPUCommand::ENABLE_ROS, std::move(buf));
103 // 等待并解析响应,获取启用是否成功的布尔值
104 auto response = fut.get();
105 bool res = (*reinterpret_cast<bool *>(response.buffer.data()));
106 } else {
107 log_error("enable_for_ros for sensor", sensor_id, " not found on any server");
108 }
109}
110
111// 发送禁用ROS相关功能的命令给特定传感器所在的辅助服务器(如果传感器已在某辅助服务器中激活)
112// 参数sensor_id: 传感器的ID,功能和逻辑与SendEnableForROS类似,只是命令类型变为MultiGPUCommand::DISABLE_ROS,用于禁用操作
114 // 搜索传感器是否已在任何辅助服务器中激活
115 auto it = _servers.find(sensor_id);
116 if (it!= _servers.end()) {
117 // 如果找到传感器,封装 sensor_id 成 carla::Buffer
118 carla::Buffer buf((carla::Buffer::value_type *) &sensor_id,
119 (size_t) sizeof(stream_id));
120// 使用 _router->WriteToOne() 向目标服务器发送禁用 ROS 命令,命令类型为 MultiGPUCommand::DISABLE_ROS
121 auto fut = _router->WriteToOne(it->second, MultiGPUCommand::DISABLE_ROS, std::move(buf));
122
123 // 等待并解析响应,获取禁用是否成功的布尔值
124 auto response = fut.get();
125 bool res = (*reinterpret_cast<bool *>(response.buffer.data()));
126 } else {
127 log_error("disable_for_ros for sensor", sensor_id, " not found on any server");
128 }
129}
130
131// 发送查询特定传感器是否已启用ROS相关功能的命令给对应的辅助服务器(如果传感器已在某辅助服务器中激活),并返回查询结果
132// 参数sensor_id: 传感器的ID,同样先查找传感器所在服务器,如果找到:
133// - 通过路由器的WriteToOne方法发送查询命令(命令类型为MultiGPUCommand::IS_ENABLED_ROS),等待响应并解析出布尔值结果(表示是否启用),然后返回该结果
134// 如果没找到对应的服务器,记录错误日志,并返回false表示未找到该传感器对应的服务器,默认当作未启用
136 // 搜索传感器是否已在任何辅助服务器中激活
137 auto it = _servers.find(sensor_id);// 在_servers中查找传感器sensor_id对应的服务器
138 if (it!= _servers.end()) { // 如果找到了对应的服务器
139 //创建缓冲区并通过路由器向服务器发送命令
140 carla::Buffer buf((carla::Buffer::value_type *) &sensor_id,
141 (size_t) sizeof(stream_id));
142 // 调用WriteToOne方法,发送IS_ENABLED_ROS命令到找到的服务器
143 auto fut = _router->WriteToOne(it->second, MultiGPUCommand::IS_ENABLED_ROS, std::move(buf));
144 // 等待异步操作完成,获取服务器的响应
145 auto response = fut.get();// 等待命令执行完成并获取响应
146 // 解析响应数据,获取布尔值结果(是否启用ROS功能)
147 bool res = (*reinterpret_cast<bool *>(response.buffer.data()));
148 return res; // 返回是否启用了ROS功能
149 } else {
150 // 如果没有找到对应的服务器,记录错误日志并返回false
151 log_error("is_enabled_for_ros for sensor", sensor_id, " not found on any server");
152 return false; // 默认认为该传感器没有启用ROS功能
153 }
154}
155
156// 获取特定传感器的令牌(token)的函数
157// 参数sensor_id: 传感器的ID,首先在已记录的令牌列表(_tokens)中查找该传感器是否已有对应的令牌,如果有:
158// - 直接返回已有的令牌(从记录中获取并返回,同时记录日志信息表明使用已激活传感器的令牌)
159// 如果没有找到对应的令牌,则执行以下操作:
160// - 通过路由器获取下一个可用的服务器(_router->GetNextServer())
161// - 调用SendGetToken函数向该服务器请求获取令牌
162// - 将获取到的令牌添加到令牌列表(_tokens)和服务器列表(_servers)中,记录日志信息表明使用新激活传感器的令牌,最后返回该令牌
164 // 搜索传感器是否已在任何辅助服务器中激活
165 auto it = _tokens.find(sensor_id);
166 if (it!= _tokens.end()) {
167 // 返回已经激活的传感器令牌
168 log_debug("Using token from already activated sensor: ", it->second.get_stream_id(), ", ", it->second.get_port());
169 return it->second; // 直接返回已找到的令牌
170 }
171 else {
172 // 在一台辅助服务器上启用传感器
173 auto server = _router->GetNextServer();
174 // 向该服务器请求获取令牌
175 auto token = SendGetToken(sensor_id);
176 // add to the maps
177 // 将获取到的令牌和服务器添加到令牌列表(_tokens)和服务器列表(_servers)中
178 _tokens[sensor_id] = token;
179 _servers[sensor_id] = server;
180 //记录日志,表示新激活传感器的令牌
181 log_debug("Using token from new activated sensor: ", token.get_stream_id(), ", ", token.get_port());
182 // 返回新的令牌
183 return token;
184 }
185}
186
187// 启用特定传感器的ROS相关功能的函数
188// 参数sensor_id: 传感器的ID,首先在服务器列表(_servers)中查找该传感器是否已在某个辅助服务器中激活,如果找到:
189// - 直接调用SendEnableForROS函数发送启用命令
190// 如果没找到对应的服务器,则先调用GetToken函数获取该传感器的令牌(这可能会激活传感器并记录相关信息),然后再次调用EnableForROS函数自身(递归调用)尝试启用
192 auto it = _servers.find(sensor_id); // 查找传感器ID是否在服务器列表中
193 if (it!= _servers.end()) { // 如果在服务器中找到了对应的传感器
194 SendEnableForROS(sensor_id); // 直接调用SendEnableForROS启用该传感器
195 } else {
196 // 我们需要在任何服务器上激活传感器,然后重复
197 GetToken(sensor_id); // 获取令牌,可能激活传感器并记录信息
198 EnableForROS(sensor_id);// 递归调用EnableForROS来重新启用传感器
199 }
200}
201
202// 禁用特定传感器的ROS相关功能的函数
203// 参数sensor_id: 传感器的ID,在服务器列表(_servers)中查找该传感器是否已在某个辅助服务器中激活,如果找到:
204// - 调用SendDisableForROS函数发送禁用命令
206 auto it = _servers.find(sensor_id); // 查找传感器ID是否在服务器列表中
207 if (it!= _servers.end()) { // 如果在服务器中找到了对应的传感器
208 SendDisableForROS(sensor_id); // 直接调用SendDisableForROS禁用该传感器
209 }
210}
211
212// 查询特定传感器是否已启用ROS相关功能的函数
213// 参数sensor_id: 传感器的ID,在服务器列表(_servers)中查找该传感器是否已在某个辅助服务器中激活,如果找到:
214// - 调用SendIsEnabledForROS函数发送查询命令,并返回查询结果
215// 如果没找到对应的服务器,直接返回false,表示未启用
217 auto it = _servers.find(sensor_id); // 查找传感器ID是否在服务器列表中
218 if (it!= _servers.end()) { // 如果在服务器中找到了对应的传感器
219 return SendIsEnabledForROS(sensor_id); // 查询该传感器是否启用了ROS功能
220 }
221 }
222 return false; // 如果没有找到传感器,则返回false,表示未启用
223}
224
225} // namespace multigpu
226} // namespace carla
包含 Carla 框架中与网络流相关的类和函数的声明。
包含与Carla流处理相关的底层细节的头文件。
一块原始数据。 请注意,如果需要更多容量,则会分配一个新的内存块,并 删除旧的内存块。这意味着默认情况下,缓冲区只能增长。要释放内存,使用 clear 或 pop。
unsigned char value_type
void SendEnableForROS(stream_id sensor_id)
std::unordered_map< stream_id, token_type > _tokens
void set_router(std::shared_ptr< Router > router)
void DisableForROS(stream_id sensor_id)
bool SendIsEnabledForROS(stream_id sensor_id)
token_type GetToken(stream_id sensor_id)
void SendFrameData(carla::Buffer buffer)
void EnableForROS(stream_id sensor_id)
std::unordered_map< stream_id, std::weak_ptr< Primary > > _servers
token_type SendGetToken(carla::streaming::detail::stream_id_type sensor_id)
void SendDisableForROS(stream_id sensor_id)
bool IsEnabledForROS(stream_id sensor_id)
std::shared_ptr< Router > _router
静态断言,用于确保token_data结构体的大小与Token::data的大小相同。
const auto & get_stream_id() const
获取流ID的引用。
auto get_port() const
获取端口号。
包含CARLA流处理相关头文件和Boost.Asio网络库头文件。 包含CARLA的调试功能相关定义。 包含CARLA流处理的端点(EndPoint)类定义。 包含CARLA流处理的令牌(Token)类...
carla::streaming::detail::stream_id_type stream_id
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
static void log_error(Args &&... args)
Definition Logging.h:115
static void log_info(Args &&... args)
Definition Logging.h:86
static void log_debug(Args &&... args)
Definition Logging.h:71