yaml解析自定义结构
直接看官方例程1:
struct Vec3 { double x, y, z; /* etc - make sure you have overloaded operator== */ };
// 实际使用来看并不需要重载 operator==
namespace YAML {
template<>
struct convert<Vec3> {
static Node encode(const Vec3& rhs) {
Node node;
node.push_back(rhs.x);
node.push_back(rhs.y);
node.push_back(rhs.z);
return node;
}
static bool decode(const Node& node, Vec3& rhs) {
if(!node.IsSequence() || node.size() != 3) {
return false;
}
rhs.x = node[0].as<double>();
rhs.y = node[1].as<double>();
rhs.z = node[2].as<double>();
return true;
}
};
}
YAML::Node node = YAML::Load("start: [1, 3, 0]");
Vec3 v = node["start"].as<Vec3>();
node["end"] = Vec3(2, -1, 0);
个人认为最值得注意的部分是:
if(!node.IsSequence() || node.size() != 3) {
return false;
}
用来校验node的合法性。
个人使用样例:
YAML文件
topics_config:
- is_record: false
wildcard_path: ["/perception/users/qiuzhongyuan/datasets/at128/xingyueL/demo_shanqi/*.pcd"]
topic_name: /at128
begin_msg_idx: 0
msg_count: 2000
msg_config:
type: sensor_msgs/msg/PointCloud2
encoding: bgr8
scale: 1
padding_top: 0
padding_bottom: 0
padding_left: 0
padding_right: 0
lidar_type: at128
viewed_scale: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- is_record: false
wildcard_path: ["/perception/custom_datasets/nova_pilot/mod/train/image/highway/cam9/0727/*.jpg"]
topic_name: /vis_topic_image
begin_msg_idx: 2000
msg_count: 2000
msg_config:
type: sensor_msgs/msg/CompressedImage
encoding: rgb8
scale: 1
padding_top: 0
padding_bottom: 0
padding_left: 0
padding_right: 0
lidar_type: at128
viewed_scale: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
结构体定义和自定义编解码
struct TopicConfig {
bool isRecord;
std::vector<std::string> wildcardPath;
std::string topicName;
int beginMsgIdx;
int msgCount;
std::string msgType;
std::string imgEncoding;
int scale;
int paddingTop;
int paddingBottom;
int paddingLeft;
int paddingRight;
std::string lidarType;
std::vector<double> viewedScale;
TopicConfig() :
isRecord(false),
wildcardPath({}),
topicName(""),
beginMsgIdx(0),
msgCount(0),
msgType(""),
imgEncoding(""),
scale(1),
paddingTop(0),
paddingBottom(0),
paddingLeft(0),
paddingRight(0),
lidarType(""),
viewedScale({0.0, 0.0, 0.0, 0.0, 0.0, 0.0})
{};
};
namespace YAML {
template<>
struct convert<TopicConfig> {
static Node encode(const TopicConfig& config) {
Node node;
node["is_record"] = config.isRecord;
node["wildcard_path"] = config.wildcardPath;
node["topic_name"] = config.topicName;
node["begin_msg_idx"] = config.beginMsgIdx;
node["msg_count"] = config.msgCount;
node["msg_config"]["type"] = config.msgType;
node["msg_config"]["encoding"] = config.imgEncoding;
node["msg_config"]["scale"] = config.scale;
node["msg_config"]["padding_top"] = config.paddingTop;
node["msg_config"]["padding_bottom"] = config.paddingBottom;
node["msg_config"]["padding_left"] = config.paddingLeft;
node["msg_config"]["padding_right"] = config.paddingRight;
node["msg_config"]["lidar_type"] = config.lidarType;
node["msg_config"]["viewed_scale"] = config.viewedScale;
return node;
}
static bool decode(const Node& node, TopicConfig& config) {
// 使用如下的方式来校验每一个key的有效性
if (!node["is_record"] || !node["wildcard_path"] ||
!node["topic_name"] || !node["begin_msg_idx"] ||
!node["msg_count"] || !node["msg_config"]["type"] || !node["msg_config"]["encoding"] ||
!node["msg_config"]["scale"] || !node["msg_config"]["padding_top"] ||
!node["msg_config"]["padding_bottom"] || !node["msg_config"]["padding_left"] ||
!node["msg_config"]["padding_right"] ||
!node["msg_config"]["lidar_type"] || !node["msg_config"]["viewed_scale"]) {
return false;
}
config.isRecord = node["is_record"].as<bool>();
config.wildcardPath = node["wildcard_path"].as<std::vector<std::string>>();
config.topicName = node["topic_name"].as<std::string>();
config.beginMsgIdx = node["begin_msg_idx"].as<int>();
config.msgCount = node["msg_count"].as<int>();
config.msgType = node["msg_config"]["type"].as<std::string>();
config.imgEncoding = node["msg_config"]["encoding"].as<std::string>();
config.scale = node["msg_config"]["scale"].as<int>();
config.paddingTop = node["msg_config"]["padding_top"].as<int>();
config.paddingBottom = node["msg_config"]["padding_bottom"].as<int>();
config.paddingLeft = node["msg_config"]["padding_left"].as<int>();
config.paddingRight = node["msg_config"]["padding_right"].as<int>();
config.lidarType = node["msg_config"]["lidar_type"].as<std::string>();
config.viewedScale = node["msg_config"]["viewed_scale"].as<std::vector<double>>();
return true;
}
};
}
使用
YAML::Node config = YAML::LoadFile("file.yaml");
std::vector<TopicConfig> = config["topics_config"].as<std::vector<TopicConfig>>();