我是靠谱客的博主 年轻手机,最近开发中收集的这篇文章主要介绍Carla框架分析(三),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Carla采用的是CS的架构,即

  • Server端是在UE4当中,作为UE4的一个插件Plugin
  • Client端是C++客户端或者是Python客户端
  • 中间通过rpc框架进行通信,走的是TCP协议

首先来看一张很重要的图

这张图清晰明了的说明了Carla的整体框架,接下来我们一个一个分析

RPC框架

建议读者先要理解RPC框架才往后阅读

Carla所使用的是rpc框架是rpclib,可以在github上找到:地址

或者在Build/rpclib-src目录下

LibCarla

LibCarla是Carla的核心代码C++实现,提供给Server端和Client端使用,同时对rpclib进行了封装,具体目录在LibCarlasourcecarla下,其中LibCarlasourcethird-party则是Carla所使用的第三方库

我们可以在LibCarlacmake目录中看到以下目录结构,说明Server端和Client端是分开构建的

  • Server端依赖的代码在Carla构建完之后会被安装到UnrealCarlaUE4PluginsCarlaCarlaDependencies目录下
  • Client端依赖的代码在Carla构建完之后会被安装到PythonAPIcarladependencies目录下

Server端

Server端的代码在Unreal/CarlaUE4/Plugins/Carla/Source/Carla目录下,其中Server/CarlaServer.cpp里包含了Carla对rpc::Server的一个封装

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class ServerBinder { public: constexpr ServerBinder(const char *name, carla::rpc::Server &srv, bool sync) : _name(name), _server(srv), _sync(sync) {} template <typename FuncT> auto operator<<(FuncT func) { if (_sync) { _server.BindSync(_name, func); } else { _server.BindAsync(_name, func); } return func; } private: const char *_name; carla::rpc::Server &_server; bool _sync; }; #define BIND_SYNC(name) auto name = ServerBinder(# name, Server, true) #define BIND_ASYNC(name) auto name = ServerBinder(# name, Server, false) // ============================================================================= // -- Bind Actions ------------------------------------------------------------- // ============================================================================= void FCarlaServer::FPimpl::BindActions() { namespace cr = carla::rpc; namespace cg = carla::geom; /// Looks for a Traffic Manager running on port BIND_SYNC(is_traffic_manager_running) << [this] (uint16_t port) ->R<bool> { return (TrafficManagerInfo.find(port) != TrafficManagerInfo.end()); }; // ... 其余代码 }

通过源码可以看到,BIND_SYNCBIND_ASYNC两个宏实现了Server端函数调用的绑定,例如:is_traffic_manager_running函数

Client端(C++)

我们可以在LibCarlasourcecarlaclientdetailClient.cpp中找到Client端的实现代码,不过如果你要编写的是C++的Client的话,你可以从PythonAPIcarladependencies目录下拿取安装好的

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class Client::Pimpl { public: Pimpl(const std::string &host, uint16_t port, size_t worker_threads) : endpoint(host + ":" + std::to_string(port)), rpc_client(host, port), streaming_client(host) { rpc_client.set_timeout(5000u); streaming_client.AsyncRun( worker_threads > 0u ? worker_threads : std::thread::hardware_concurrency()); } template <typename ... Args> auto RawCall(const std::string &function, Args && ... args) { try { return rpc_client.call(function, std::forward<Args>(args) ...); } catch (const ::rpc::timeout &) { throw_exception(TimeoutException(endpoint, GetTimeout())); } } template <typename T, typename ... Args> auto CallAndWait(const std::string &function, Args && ... args) { auto object = RawCall(function, std::forward<Args>(args) ...); using R = typename carla::rpc::Response<T>; auto response = object.template as<R>(); if (response.HasError()) { throw_exception(std::runtime_error(response.GetError().What())); } return Get(response); } template <typename ... Args> void AsyncCall(const std::string &function, Args && ... args) { // Discard returned future. rpc_client.async_call(function, std::forward<Args>(args) ...); } time_duration GetTimeout() const { auto timeout = rpc_client.get_timeout(); DEBUG_ASSERT(timeout.has_value()); return time_duration::milliseconds(static_cast<size_t>(*timeout)); } const std::string endpoint; rpc::Client rpc_client; streaming::Client streaming_client; }; Client::Client( const std::string &host, const uint16_t port, const size_t worker_threads) : _pimpl(std::make_unique<Pimpl>(host, port, worker_threads)) {} bool Client::IsTrafficManagerRunning(uint16_t port) const { return _pimpl->CallAndWait<bool>("is_traffic_manager_running", port); }

通过源码可以看到,Client端调用了Server端的函数is_traffic_manager_running

Client端(Python)

目录:PythonAPIcarlasourcelibcarla,主要是通过boost::python来实现C++到Python的绑定

我们随便看一个文件,例如PythonAPIcarlasourcelibcarlaActor.cpp文件,具体的绑定用法需要读者自己去了解boost::python

最后

以上就是年轻手机为你收集整理的Carla框架分析(三)的全部内容,希望文章能够帮你解决Carla框架分析(三)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(74)

评论列表共有 0 条评论

立即
投稿
返回
顶部