CARLA
 
载入中...
搜索中...
未找到
ActorAttribute.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// 引入头文件,包含了 ActorAttribute 的定义。
8// 引入其他必要的头文件。
9#include "carla/Exception.h"
10#include "carla/Logging.h"
11#include "carla/StringUtil.h"
12
13// 使用命名空间,避免命名冲突。
14namespace carla {
15namespace client {
16
17// 定义一个宏,用于方便地抛出表示属性值无效的异常。
18// 它会调用 throw_exception 函数(应该在相关异常处理模块定义)抛出 InvalidAttributeValue 类型的异常,
19// 异常信息包含属性的标识(通过 GetId() 获取)以及传入的具体错误提示消息。
20#define LIBCARLA_THROW_INVALID_VALUE(message) throw_exception(InvalidAttributeValue(GetId() + ": " + message));
21
22// 定义一个宏,用于在属性值类型转换时进行类型检查并抛出异常。
23// 如果当前属性的类型(通过 GetType() 获取)与期望转换的类型(由参数 type 指定)不一致,
24// 就会抛出 BadAttributeCast 类型的异常,异常信息包含属性标识以及说明不能转换到指定类型的提示内容。
25#define LIBCARLA_THROW_BAD_VALUE_CAST(type) \
26 if (GetType()!= rpc::ActorAttributeType:: type) { \
27 throw_exception(BadAttributeCast(GetId() + ": bad attribute cast: cannot convert to " #type)); \
28 }
29
30// ActorAttribute 的成员函数 Set,用于设置属性值。
31 void ActorAttribute::Set(std::string value) {
32 // _attribute 应该是 ActorAttribute 类内部用于管理属性相关信息的结构体或成员对象等。
33 // 这里判断属性是否可修改,如果不可修改(_attribute.is_modifiable 为 false),
34 // 意味着该属性是只读的,此时就通过宏抛出属性值无效的异常,提示是只读属性不能设置值。
36 LIBCARLA_THROW_INVALID_VALUE("read-only attribute");
37 }
38 // 如果属性类型是布尔类型(通过 GetType() 判断),
39 // 则调用 StringUtil 命名空间下的 ToLower 函数将传入的表示布尔值的字符串转换为小写形式,
40 // 方便后续统一格式进行布尔值的判断和处理。
43 }
44 // 使用 std::move 进行移动语义赋值,将传入的 value 字符串高效地转移资源所有权给 _attribute.value,
45 // 完成对属性值的设置,避免不必要的拷贝开销。
46 _attribute.value = std::move(value);
47 // 调用 Validate 函数(应该是对刚设置的属性值进行合法性、有效性验证的函数)来确保设置的属性值符合要求。
48 // 如果验证过程中发现不符合要求的情况,会根据具体验证逻辑抛出相应的异常。
49 Validate();
50 }
51
52// 模板特化,用于将属性值转换为布尔类型。
53 template <>
55 // 首先进行类型检查,确保当前属性的类型是布尔类型,如果不是就通过宏抛出类型转换错误的异常,
56 // 提示不能转换到布尔类型。
58 // 调用 StringUtil 命名空间下的 ToLowerCopy 函数,获取属性值对应的小写形式字符串副本,
59 // 避免修改原字符串,用于后续准确判断是否为有效的布尔值表示形式。
60 auto value = StringUtil::ToLowerCopy(GetValue());
61 // 如果获取到的小写字符串值为 "true",则返回 true,表示解析为布尔真。
62 if (value == "true") {
63 return true;
64 }
65 // 如果获取到的小写字符串值为 "false",则返回 false,表示解析为布尔假。
66 else if (value == "false") {
67 return false;
68 }
69 // 如果获取到的字符串既不是 "true" 也不是 "false",则说明不是有效的布尔值表示形式,
70 // 通过宏抛出属性值无效的异常,异常信息包含提示是无效的布尔值以及具体传入的属性值内容。
71 LIBCARLA_THROW_INVALID_VALUE("invalid bool: " + GetValue());
72 }
73
74// 模板特化,用于将属性值转换为整数类型。
75 template<>
77 // 先进行类型检查,确保当前属性的类型是整数类型,如果不是就通过宏抛出类型转换错误的异常,
78 // 提示不能转换到整数类型。
80 // 使用 std::atoi 函数将表示整数的字符串(通过 GetValue() 获取属性值对应的字符串)转换为整数类型返回。
81 // std::atoi 会尝试解析字符串开头的连续数字字符部分为整数,如果字符串无法正确解析为整数可能会导致未定义行为,
82 // 但在这里应该是期望属性值对应的字符串是合法的整数表示形式。
83 return std::atoi(GetValue().c_str());
84 }
85
86// 模板特化,用于将属性值转换为浮点数类型。
87 template<>
89 // 首先进行类型检查,确保当前属性的类型是浮点数类型,如果不是就通过宏抛出类型转换错误的异常,
90 // 提示不能转换到浮点数类型。
92 // 使用 std::atof 函数将表示浮点数的字符串(通过 GetValue() 获取属性值对应的字符串)转换为双精度浮点数类型。
93 double x = std::atof(GetValue().c_str());
94 // 检查转换后的双精度浮点数是否超出了单精度浮点数的表示范围(最大值和最小值),
95 // 如果超出范围,就通过宏抛出属性值无效的异常,提示浮点数溢出。
96 if ((x > std::numeric_limits<float>::max()) ||
97 (x < std::numeric_limits<float>::lowest())) {
98 LIBCARLA_THROW_INVALID_VALUE("float overflow");
99 }
100 // 将双精度浮点数通过 static_cast 强制转换为单精度浮点数并返回,完成属性值到浮点数类型的转换。
101 return static_cast<float>(x);
102 }
103
104 template <>
105 std::string ActorAttributeValueAccess::As<std::string>() const {
106 // 进行类型检查,确保当前属性的类型是字符串类型,如果不是就通过宏抛出类型转换错误的异常,
107 // 提示不能转换到字符串类型。
109 // 如果属性类型是字符串类型,直接返回通过 GetValue() 获取到的属性值对应的字符串,完成转换操作。
110 return GetValue();
111 }
112
113// 模板特化,用于将属性值转换为传感器数据颜色类型。
114 template <>
115 sensor::data::Color ActorAttributeValueAccess::As<sensor::data::Color>() const {
116 // 先进行类型检查,确保当前属性的类型是 RGBColor(传感器数据颜色相关类型,这里应该是对应颜色表示的一种类型定义)类型,
117 // 如果不是就通过宏抛出类型转换错误的异常,提示不能转换到该颜色类型。
119 // 定义一个 std::vector<std::string> 类型的容器 channels,用于存储分割后的颜色通道字符串。
120 std::vector<std::string> channels;
121 // 调用 StringUtil 命名空间下的 Split 函数,将属性值对应的字符串(通过 GetValue() 获取)按照逗号分隔符进行分割,
122 // 分割后的各个子字符串分别代表颜色的红、绿、蓝三个通道值,存储在 channels 容器中。
123 StringUtil::Split(channels, GetValue(), ",");
124 // 检查分割后得到的颜色通道数量是否为 3 个,如果不是则说明颜色表示格式不正确,
125 // 通过日志记录函数(log_error,应该在 carla/Logging.h 中定义)记录错误信息,
126 // 并通过宏抛出属性值无效的异常,提示颜色必须有 3 个通道(即 R、G、B 三个通道)。
127 if (channels.size()!= 3u) {
128 log_error("invalid color", GetValue());
129 LIBCARLA_THROW_INVALID_VALUE("colors must have 3 channels (R,G,B)");
130 }
131 // 定义一个 lambda 表达式,用于将表示颜色通道的字符串转换为无符号 8 位整数(uint8_t)类型。
132 // 先使用 std::atoi 将字符串转换为整数,然后检查转换后的整数是否超出了 uint8_t 类型能表示的最大值范围,
133 // 如果超出范围就通过宏抛出属性值无效的异常,提示颜色通道整数溢出,
134 // 如果在范围内则将整数强制转换为 uint8_t 类型并返回。
135 auto to_int = [this](const std::string &str) {
136 int i = std::atoi(str.c_str());
137 if (i > std::numeric_limits<uint8_t>::max()) {
138 LIBCARLA_THROW_INVALID_VALUE("integer overflow in color channel");
139 }
140 return static_cast<uint8_t>(i);
141 };
142 // 使用定义好的 lambda 表达式将三个通道的字符串分别转换为无符号 8 位整数,
143 // 然后构造并返回一个 sensor::data::Color 类型的对象(代表颜色值),其参数分别为三个通道对应的整数值。
144 return {to_int(channels[0u]), to_int(channels[1u]), to_int(channels[2u])};
145 }
146
147// 验证属性值的有效性,根据属性类型进行相应的类型转换并检查是否抛出异常。
149 // 根据属性的类型(通过 GetType() 获取)使用 switch 语句进行不同情况的处理。
150 switch (GetType()) {
151 // 如果属性类型是布尔类型,调用 As<rpc::ActorAttributeType::Bool>() 函数进行布尔类型的转换验证,
152 // 如果转换过程中出现问题(比如类型不对、值格式不对等)会抛出相应的异常,这里只是调用进行验证流程。
154 // 如果属性类型是整数类型,调用 As<rpc::ActorAttributeType::Int>() 函数进行整数类型的转换验证。
156 // 如果属性类型是浮点数类型,调用 As<rpc::ActorAttributeType::Float>() 函数进行浮点数类型的转换验证。
158 // 如果属性类型是字符串类型,调用 As<rpc::ActorAttributeType::String>() 函数进行字符串类型的转换验证。
160 // 如果属性类型是 RGBColor(传感器数据颜色类型),调用 As<rpc::ActorAttributeType::RGBColor>() 函数进行颜色类型的转换验证。
162 // 如果属性类型不属于上述任何一种已知的合法类型,就通过宏抛出属性值无效的异常,提示是无效的值类型。
163 default:
164 LIBCARLA_THROW_INVALID_VALUE("invalid value type");
165 }
166 }
167
168#undef LIBCARLA_THROW_BAD_VALUE_CAST
169#undef LIBCARLA_THROW_INVALID_VALUE
170
171} // namespace client
172} // namespace carla
#define LIBCARLA_THROW_BAD_VALUE_CAST(type)
#define LIBCARLA_THROW_INVALID_VALUE(message)
static void Split(Container &destination, const Range1T &str, const Range2T &separators)
Definition StringUtil.h:75
static auto ToLowerCopy(const SequenceT &str)
Definition StringUtil.h:46
static void ToLower(WritableRangeT &str)
Definition StringUtil.h:40
virtual const std::string & GetValue() const =0
virtual rpc::ActorAttributeType GetType() const =0
T As() const
将值转换为给定的类型。
void Set(std::string value)
设置这个属性值
virtual rpc::ActorAttributeType GetType() const override
auto ActorAttributeValueAccess::As< rpc::ActorAttributeType::String >() const
auto ActorAttributeValueAccess::As< rpc::ActorAttributeType::Bool >() const
auto ActorAttributeValueAccess::As< rpc::ActorAttributeType::RGBColor >() const
auto ActorAttributeValueAccess::As< rpc::ActorAttributeType::Float >() const
auto ActorAttributeValueAccess::As< rpc::ActorAttributeType::Int >() const
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
static void log_error(Args &&... args)
Definition Logging.h:115
包含CARLA客户端相关类和函数的命名空间。