Carla框架分析(三)

Carla采用的是CS的架構(gòu)雷则,即

  • Server端是在UE4當(dāng)中,作為UE4的一個插件Plugin
  • Client端是C++客戶端或者是Python客戶端
  • 中間通過rpc框架進(jìn)行通信褐望,走的是TCP協(xié)議

首先來看一張很重要的圖

image

這張圖清晰明了的說明了Carla的整體框架,接下來我們一個一個分析

RPC框架

建議讀者先要理解RPC框架才往后閱讀

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

或者在Build/rpclib-src目錄下

LibCarla

LibCarla是Carla的核心代碼C++實現(xiàn)拦耐,提供給Server端和Client端使用,同時對rpclib進(jìn)行了封裝榕暇,具體目錄在LibCarla\source\carla下蓬衡,其中LibCarla\source\third-party則是Carla所使用的第三方庫

我們可以在LibCarla\cmake目錄中看到以下目錄結(jié)構(gòu)喻杈,說明Server端和Client端是分開構(gòu)建的

image
  • Server端依賴的代碼在Carla構(gòu)建完之后會被安裝到Unreal\CarlaUE4\Plugins\Carla\CarlaDependencies目錄下
  • Client端依賴的代碼在Carla構(gòu)建完之后會被安裝到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_SYNCBIND_ASYNC兩個宏實現(xiàn)了Server端函數(shù)調(diào)用的綁定筒饰,例如:is_traffic_manager_running函數(shù)

Client端(C++)

我們可以在LibCarla\source\carla\client\detail\Client.cpp中找到Client端的實現(xiàn)代碼,不過如果你要編寫的是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端調(diào)用了Server端的函數(shù)is_traffic_manager_running

Client端(Python)

目錄:PythonAPI\carla\source\libcarla,主要是通過boost::python來實現(xiàn)C++到Python的綁定

我們隨便看一個文件秒咐,例如PythonAPI\carla\source\libcarla\Actor.cpp文件谬晕,具體的綁定用法需要讀者自己去了解boost::python

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市携取,隨后出現(xiàn)的幾起案子攒钳,更是在濱河造成了極大的恐慌,老刑警劉巖雷滋,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件不撑,死亡現(xiàn)場離奇詭異,居然都是意外死亡晤斩,警方通過查閱死者的電腦和手機(jī)焕檬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來澳泵,“玉大人实愚,你說我怎么就攤上這事⊥酶ǎ” “怎么了爆侣?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長幢妄。 經(jīng)常有香客問我兔仰,道長,這世上最難降的妖魔是什么蕉鸳? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任乎赴,我火速辦了婚禮,結(jié)果婚禮上潮尝,老公的妹妹穿的比我還像新娘榕吼。我一直安慰自己,他們只是感情好勉失,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布羹蚣。 她就那樣靜靜地躺著,像睡著了一般乱凿。 火紅的嫁衣襯著肌膚如雪顽素。 梳的紋絲不亂的頭發(fā)上咽弦,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天,我揣著相機(jī)與錄音胁出,去河邊找鬼型型。 笑死,一個胖子當(dāng)著我的面吹牛全蝶,可吹牛的內(nèi)容都是我干的闹蒜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼抑淫,長吁一口氣:“原來是場噩夢啊……” “哼绷落!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起始苇,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤砌烁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后埂蕊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體往弓,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡疏唾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年蓄氧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片槐脏。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡喉童,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出顿天,到底是詐尸還是另有隱情堂氯,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布牌废,位于F島的核電站咽白,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鸟缕。R本人自食惡果不足惜晶框,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望懂从。 院中可真熱鬧授段,春花似錦、人聲如沸番甩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缘薛。三九已至窍育,卻和暖如春卡睦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蔫骂。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工么翰, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人辽旋。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓浩嫌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親补胚。 傳聞我的和親對象是個殘疾皇子码耐,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容

  • rpcx 框架 作者:李驍 嚴(yán)格來說,《Go語言四十二章經(jīng)》已經(jīng)寫完溶其,個人認(rèn)為rpcx框架整體上值得推薦骚腥,它為中小...
    ffhelicopter閱讀 8,594評論 0 13
  • 第一部分 Python基礎(chǔ)篇(80題) 1、為什么學(xué)習(xí)Python瓶逃? Python相對于其他編程語言有很多優(yōu)點: ...
    清清子衿木子水心閱讀 1,714評論 0 1
  • 1. 分布式系統(tǒng)核心問題 參考書籍:《區(qū)塊鏈原理束铭、設(shè)計與應(yīng)用》 一致性問題例子:兩個不同的電影院買同一種電影票仑撞,如...
    molscar閱讀 916評論 0 0
  • 目錄 1 應(yīng)用架構(gòu)演變 2 RPC 3 Dubbo概述 4 Dubbo配置 5 Dubbo協(xié)議 6 高...
    小小千千閱讀 565評論 0 0
  • 本文只是對官方文檔[https://carla.readthedocs.io/en/latest/build_wi...
    梁如風(fēng)閱讀 2,271評論 0 0