UE4中使用Carla——Python与C++相互类型转换,获取返回值等问题

1.简述

许多小伙伴私问我Carla中PythonAPI的开发,新增修改的问题,类型转换以及如何把UE的数据返回获取给Python端等,这次通过一个例子一并解决这些问题, 这里配合之前文章食用更佳
UE4中使用Carla——开发添加自定义PythonAPI
我们都知道C++和Python的相互类型转换,会遇到许多复杂的类型转换问题,比如Python中的列表list如何转化为C++中的容器Vector等等,我们还是根据下图的架构,以下示例按从左到右从上到下的方式,依次展示相关代码。
在这里插入图片描述

2.代码示例

举例如下:定义一个Vector<Transform>类型的数据结构,可以理解容器为一个动态数组,填充的元素按顺序排列,元素类型为transfrom类型,即位置坐标信息,有了这种数据结构你可以很方便的批量操作多个物体/点/文件等等。

设计一个函数set_patharray,它用来实现将python定义的list传递到UE中为我们所用,并给一个返回值用以返回其他感兴趣的数据,这里以int型为例, 以下为具体步骤:

  1. 在你的python文件中 定义t0 t1两个元素,并加入list中,调用set_examplepatharray函数,返回值用i存储
t0 = carla.Transform()
t0.location.x = -770.0
t0.location.y = -11000
t0.location.z = 210
t1 = carla.Transform()
t1.location.x = -7700.0
t1.location.y = -110000
t1.location.z = 210
list_b = []
list_b.append(t0)
list_b.append(t1)
i=world.player.set_examplepatharray(list_b)
  1. PythonAPI\carla\source\libcarla下的actor.cpp中:利用boost作List转vector
static int  SetExamplePathPointArray(carla::client::Actor &actor, boost::python::list& ns)
{
  std::vector<carla::geom::Transform> transformarray;
  for (int i = 0; i < len(ns); ++i)
    transformarray.push_back(boost::python::extract<carla::geom::Transform>(ns[i]));

  return actor.SetExamplePathArray(transformarray);
}

在对应类下添加相对应的函数名:

 .def("set_examplepatharray", &SetExamplePathPointArray, (arg("actor")))
  1. 在C++中直接操作vector类型即可

LibCarla\source\carla\client\Actor.h

int SetExamplePathArray(const std::vector<geom::Transform>& PathPointArray);

LibCarla\source\carla\client\Actor.cpp

  int Actor::SetExamplePathArray(const std::vector<geom::Transform>& PathPointArray)
  {
	 return GetEpisode().Lock()->SetExamplePathArray(*this, PathPointArray);
  }

LibCarla\source\carla\client\detail\Simulator.h

	int SetExamplePathArray(const Actor &actor, const std::vector<geom::Transform>& PathPointArray)
	{
		return _client.SetExamplePathArray(actor.GetId(), PathPointArray);
	}

LibCarla\source\carla\client\detail\Client.h

	int SetExamplePathArray(rpc::ActorId actor, const std::vector<geom::Transform>& PathPointArray);

LibCarla\source\carla\client\detail\Client.cpp
PS:注意_pimpl->AsyncCall和_pimpl->CallAndWait<int>的区别,这里取了int作为返回值

  int Client::SetExamplePathArray(rpc::ActorId actor, const std::vector<geom::Transform>& PathPointArray)
  {
	  return _pimpl->CallAndWait<int>("set_examplepatharray", actor, PathPointArray);
  }
  1. Plugins\Carla\Source\Carla\Server\CarlaServer.cpp 需要转成TArray<FVector>供UE使用
BIND_SYNC(set_examplepatharray) << [this](cr::ActorId ActorId, const std::vector<cr::Transform>& PathPointArray)->R<int>
	{
		REQUIRE_CARLA_EPISODE();
		auto ActorView = Episode->FindActor(ActorId);
		if (!ActorView.IsValid())
		{
			RESPOND_ERROR("unable to set actor transform: actor not found");
		}
		auto pCar = Cast<ACarlaWheeledVehicle>(ActorView.GetActor());
		if (pCar == nullptr)
			RESPOND_ERROR("unable to setpath");
		TArray<FVector> Path;
		const std::vector<carla::geom::Transform>& dataarray = PathPointArray;
		FVector dataval;
		for (uint32_t i = 0; i < dataarray.size(); i++)
		{
			dataval.X = dataarray[i].location.x;
			dataval.Y = dataarray[i].location.y;
			dataval.Z = dataarray[i].location.z;
			Path.Add(dataval);
		}
		pCar->DataCapExample_SetPathArray(Path);
		return pCar->GetDataExampleID();
	};

\Plugins\Carla\Source\Carla\Vehicle\CarlaWheeledVehicle.h

  	int m_DataExampleID;

	UFUNCTION(BlueprintImplementableEvent)
	void DataCapExample_SetPathArray(const TArray<FVector>& Path);
	UFUNCTION(Category = "CARLA Wheeled Vehicle", BlueprintCallable)
	void SetDataExampleID(int iVal) { m_DataExampleID = iVal; }
	UFUNCTION(Category = "CARLA Wheeled Vehicle", BlueprintCallable)
	int GetDataExampleID() const { return m_DataExampleID; }
  1. 如此在UE蓝图中需要对参数改变时,调用SetDataExampleID函数即可,DataCapExample_SetPathArray也作为event事件的形式,每次通过python调用一次而执行一次

如果还有别的关于carla/UE4的问题欢迎与我讨论~

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐