找回密码
 立即注册
查看: 287|回复: 0

Carla框架分析(三)

[复制链接]
发表于 2022-1-23 21:22 | 显示全部楼层 |阅读模式
Carla采用的是CS的架构,即
    Server端是在UE4当中,作为UE4的一个插件PluginClient端是C++客户端或者是Python客户端中间通过rpc框架进行通信,走的是TCP协议

首先来看一张很重要的图

image

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


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

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

或者在Build/rpclib-src目录下
LibCarla


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

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

image

    Server端依赖的代码在Carla构建完之后会被安装到Unreal\CarlaUE4\Plugins\Carla\CarlaDependencies目录下Client端依赖的代码在Carla构建完之后会被安装到PythonAPI\carla\dependencies目录下
Server端


Server端的代码在Unreal/CarlaUE4/Plugins/Carla/Source/Carla目录下,其中Server/CarlaServer.cpp里包含了Carla对rpc::Server的一个封装
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_SYNC和BIND_ASYNC两个宏实现了Server端函数调用的绑定,例如:is_traffic_manager_running函数
Client端(C++)


我们可以在LibCarla\source\carla\client\detail\Client.cpp中找到Client端的实现代码,不过如果你要编写的是C++的Client的话,你可以从PythonAPI\carla\dependencies目录下拿取安装好的
  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)


目录:PythonAPI\carla\source\libcarla,主要是通过boost::python来实现C++到Python的绑定

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

image

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-22 21:29 , Processed in 0.230292 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表