行人的实现分析

调用过程

使用 manual_control.py 生成行人:

self.world.try_spawn_actor(blueprint, spawn_point)

hutb/PythonAPI/carla/source/libcarla/World.cpp 中定义了 try_spawn_action() 调用 TrySpawnActor。

.def("try_spawn_actor", SPAWN_ACTOR_WITHOUT_GIL(TrySpawnActor))

然后调用 LibCarla/source/carla/client/World.cpp 的 TrySpawnActor()

SharedPtr<Actor> World::TrySpawnActor(
    ...
    return SpawnActor(blueprint, transform, parent_actor, attachment_type, socket_name);
    ...
}
然后调用 World.cpp 的 SpwanActor()
SharedPtr<Actor> World::SpawnActor(
  ...
  return _episode.Lock()->SpawnActor(blueprint, transform, parent_actor, attachment_type, GarbageCollectionPolicy::Inherit, socket_name);
}
调用了 client/detail/EpisodeProxy.cpp 的 Lock(),返回 EpisodeProxyImpl
template <typename T>
typename EpisodeProxyImpl<T>::SharedPtrType EpisodeProxyImpl<T>::Lock() const {
  auto ptr = Load(_simulator);
  if (ptr == nullptr) {
    throw_exception(std::runtime_error(
        "trying to operate on a destroyed actor; an actor's function "
        "was called, but the actor is already destroyed."));
  }
  return ptr;
}
获得模拟器 _simulator 的指针。并调用 client/detail/Simulator.cpp 的 SpawnActor()
SharedPtr<Actor> Simulator::SpawnActor(
  const ActorBlueprint &blueprint,
  const geom::Transform &transform,
  Actor *parent,
  rpc::AttachmentType attachment_type,
  GarbageCollectionPolicy gc,
  const std::string& socket_name) {
        rpc::Actor actor;
        if (parent != nullptr) {
          actor = _client.SpawnActorWithParent(
              blueprint.MakeActorDescription(),
              transform,
              parent->GetId(),
              attachment_type,
              socket_name);
        } else {
          actor = _client.SpawnActor(
              blueprint.MakeActorDescription(),
              transform);
        }
        ...


调用 CarlaUE4 Server 模块的 CarlaServer.cpp 的:

BIND_SYNC(spawn_actor) << [this](
    cr::ActorDescription Description,
    const cr::Transform &Transform) -> R<cr::Actor>
{
  REQUIRE_CARLA_EPISODE();

  auto Result = Episode->SpawnActorWithInfo(Transform, std::move(Description));
  ...

调用 Game 模块的 CarlaEpisode.h 中的 SpawnActor()

UFUNCTION(BlueprintCallable)
AActor *SpawnActor(
    const FTransform &Transform,
    FActorDescription ActorDescription)
{
  return SpawnActorWithInfo(Transform, std::move(ActorDescription)).Value->GetActor();
}

调用 CarlaEpisode.cpp 中的 SpawnActorWithInfo()

TPair<EActorSpawnResultStatus, FCarlaActor*> UCarlaEpisode::SpawnActorWithInfo(
    const FTransform &Transform,
    FActorDescription thisActorDescription,
    FCarlaActor::IdType DesiredId)
{
  ...
  auto result = ActorDispatcher->SpawnActor(LocalTransform, thisActorDescription, DesiredId);

ActorDispatcher 的声明位于 CarlaEpisode.h

UPROPERTY(VisibleAnywhere)
UActorDispatcher *ActorDispatcher = nullptr;

行人蓝图

所有行人相关的蓝图都位于虚幻编辑器内容浏览器中的内容/Carla/Blueprints/Walkers/目录下。 每个蓝图都是一个胶囊体组件(CollisionCylinder) ,即一个 圆柱碰撞几何体 ,该集合体与其固定身体框架的 z 轴对齐,并且固定身体框架的原点位于圆柱体的中心。