组件的定义&作用
定义:通过共享的方式实现不同节点之间数据交互,参数服务器通过服务通信机制实现,服务端可以存储数据以供客户端访问,客户端此时并不需要自己实现请求与响应(有可用的API接口)。
作用:存储一些多节点共享的数据,类似于全局变量。
实列分析
需求:创建两个节点A,B。其中节点A是参数服务端,节点B作为参数客户端,A节点存储数据,B节点操作数据
实现流程:
• 创建参数服务器的服务端
• 创建参数服务器的客户端
• 编译并执行
参数说明:
通过调用Parameter封装参数,下列表格给出支持的参数类型,以及对于的C++与protobuf中的数据类型。
参数类型 | C++ data type | Protobuf data type |
apollo::cyber::proto::ParamType::INT | Int64_t | Int64 |
apollo::cyber::proto::ParamType::DOUBLE | double | double |
apollo::cyber::proto::ParamType::BOOL | bool | bool |
apollo::cyber::proto::ParamType::STRING | std::string | string |
apollo::cyber::proto::ParamType::PROTOBUF | std::string | string |
apollo::cyber::proto::ParamType::NOT_SET |
除了上述的五种类型以外,Parameter支持以protobuf 对象作为传入参数的接口。执行后的序列化处理对象并转为string类型进行传输
下面进行代码实现,创建主文件夹demo_par,创建demo_cc_ParS.cc与demo_cc_ParC.cc以及BUILD文件。
客户端代码实现:
#include "cyber/cyber.h"
#include "cyber/parameter/parameter_server.h"
using apollo::cyber::Parameter;
using apollo::cyber::ParameterServer;
int main(int argc, char *argv[]) {
apollo::cyber::Init(argv[0]);
//创建节点
std::shared_ptr<apollo::cyber::Node> server_node =
apollo::cyber::CreateNode("param");
//创建参数服务端
auto server = std::make_shared<ParameterServer>(server_node);
//增加
server->SetParameter(Parameter("cartype", "apollo_cyber_par"));
server->SetParameter(Parameter("height", 1.23));
server->SetParameter(Parameter("laser", 4));
//查找某个指定函数
Parameter temp;
server->GetParameter("cartype", &temp);
AINFO << temp.Name()
<< " == " << temp.AsString(); //.name操作是显示函数名
//.asstring是强制转换为string类型
server->GetParameter("height", &temp);
AINFO << temp.Name() << " == " << temp.AsDouble();
server->GetParameter("laser", &temp);
AINFO << temp.Name() << " == " << temp.AsInt64();
//获取所有的参数
std::vector<Parameter> ps;
server->ListParameters(&ps);
for (auto &&p : ps) //对PS进行遍历的操作
{
AINFO << p.Name() << "............" << p.TypeName() << "............"
<< p.DebugString(); // DebugString()是调试用API会显示P的各项参数
}
//修改参数
server->SetParameter(Parameter("laser", 100));
//打印观察
server->GetParameter("laser", &temp);
AINFO << temp.Name() << " == " << temp.AsInt64();
apollo::cyber::WaitForShutdown();
return 0;
}
服务端代码实现:
/**
* 参数服务被用于节点之间共享的数据,并提供了诸如基本操作set,get和list。
* 参数服务基于Service实现,并包含服务(service)和客户端(client)。
*/
/**
*explicit
*explicit(显式的)的作用是"禁止单参数构造函数"被用于自动型别转换,其中比较典型的例子就是容器类型。
*在这种类型的构造函数中你可以将初始长度作为参数传递给构造函数。
**/
#include "cyber/cyber.h"
#include "cyber/parameter/parameter_client.h"
using apollo::cyber::Parameter;
using apollo::cyber::ParameterClient;
int main(int argc, char* argv[]) {
apollo::cyber::Init(argv[0]);
//创建节点
std::shared_ptr<apollo::cyber::Node> param_client_node =
apollo::cyber::CreateNode("paramclient");
//创建参数客户端
auto param_client =
std::make_shared<ParameterClient>(param_client_node, "param");
//操作参数
Parameter temp;
param_client->GetParameter("cartype", &temp);
AINFO << temp.Name() << " == " << temp.AsString();
param_client->GetParameter("height", &temp);
AINFO << temp.Name() << " == " << temp.AsDouble();
param_client->GetParameter("laser", &temp);
AINFO << temp.Name() << " == " << temp.AsInt64();
param_client->SetParameter(Parameter("laser", 1));
AINFO << "修改后。。。。。。。。。。。。。。。。。。";
param_client->GetParameter("laser", &temp);
AINFO << temp.Name() << " == " << temp.AsInt64();
//
std::vector<Parameter> ps;
param_client->ListParameters(&ps);
for (auto&& p : ps) {
AINFO << "参数名陈" << p.Name() << ";参数类型" << p.TypeName();
}
apollo::cyber::WaitForShutdown();
return 0;
}
build文件
#******************参数通信*****************************#
cc_binary(
name = "ParS",
srcs = ["par_service.cc"],
deps = [
"//cyber",
"//cyber/parameter",
],
)
cc_binary(
name = "ParC",
srcs = ["par.cc"],
deps = [
"//cyber",
"//cyber/parameter",
],
)
脚本
parc.sh 客户端
##!/bin/sh
cd /apollo
source cyber/setup.bash
./bazel-bin/demo/cyber/parameter/ParC
pars.sh 服务端
##!/bin/sh
cd /apollo
source cyber/setup.bash
./bazel-bin/demo/cyber/parameter/ParS