Add carla.command to spawn actors in batch

This commit is contained in:
nsubiron 2019-04-03 18:22:50 +02:00
parent b29d04ea33
commit 476d587a7d
4 changed files with 103 additions and 11 deletions

View File

@ -30,11 +30,36 @@ namespace detail {
using T::operator();
};
template<typename T>
struct Recursive {
explicit Recursive(T &&func) : _func(std::move(func)) {}
template<typename... Ts>
auto operator()(Ts &&... arguments) const {
return _func(*this, std::forward<Ts>(arguments)...);
}
private:
T _func;
};
} // namespace detail
template <typename FuncT>
inline static auto MakeRecursive(FuncT &&func) {
return detail::Recursive<FuncT>(std::forward<FuncT>(func));
}
template <typename... FuncTs>
inline static auto MakeOverload(FuncTs &&... fs) {
return detail::Overload<FuncTs...>(std::forward<FuncTs>(fs)...);
}
template <typename... FuncTs>
inline static auto MakeRecursiveOverload(FuncTs &&... fs) {
return MakeRecursive(MakeOverload(std::forward<FuncTs>(fs)...));
}
} // namespace carla

View File

@ -30,6 +30,22 @@ namespace rpc {
public:
struct SpawnActor : CommandBase<SpawnActor> {
SpawnActor() = default;
SpawnActor(ActorDescription description, const geom::Transform &transform)
: description(std::move(description)),
transform(transform) {}
SpawnActor(ActorDescription description, const geom::Transform &transform, ActorId parent)
: description(std::move(description)),
transform(transform),
parent(parent) {}
ActorDescription description;
geom::Transform transform;
boost::optional<ActorId> parent;
std::vector<Command> do_after;
MSGPACK_DEFINE_ARRAY(description, transform, parent, do_after);
};
struct DestroyActor : CommandBase<DestroyActor> {
DestroyActor() = default;
DestroyActor(ActorId id) : actor(id) {}
@ -102,6 +118,7 @@ namespace rpc {
};
using CommandType = boost::variant<
SpawnActor,
DestroyActor,
ApplyVehicleControl,
ApplyWalkerControl,

View File

@ -27,6 +27,18 @@ namespace command_impl {
return self.attr("__init__")(Convert(args)...);
}
template <typename... ArgsT>
static boost::python::object CustomSpawnActorInit(boost::python::object self, ArgsT... args) {
return self.attr("__init__")(carla::rpc::Command::SpawnActor{Convert(args)...});
}
static carla::rpc::Command::SpawnActor Then(
carla::rpc::Command::SpawnActor &self,
carla::rpc::Command command) {
self.do_after.push_back(command);
return self;
}
} // namespace command_impl
void export_commands() {
@ -39,7 +51,29 @@ void export_commands() {
object command_module(handle<>(borrowed(PyImport_AddModule("libcarla.command"))));
scope().attr("command") = command_module;
scope io_scope = command_module;
scope submodule_scope = command_module;
// This is a handler for passing to "SpawnActor.then" commands.
submodule_scope.attr("FutureActor") = 0u;
class_<cr::Command::SpawnActor>("SpawnActor")
.def(
"__init__",
&command_impl::CustomSpawnActorInit<cc::ActorBlueprint, cg::Transform>,
(arg("blueprint"), arg("transform")))
.def(
"__init__",
&command_impl::CustomSpawnActorInit<cc::ActorBlueprint, cg::Transform, const cr::ActorId &>,
(arg("blueprint"), arg("transform"), arg("parent_id")))
.def(
"__init__",
&command_impl::CustomSpawnActorInit<cc::ActorBlueprint, cg::Transform, ActorPtr>,
(arg("blueprint"), arg("transform"), arg("parent")))
.def(init<cr::Command::SpawnActor>())
.def_readwrite("transform", &cr::Command::SpawnActor::transform)
.def_readwrite("parent_id", &cr::Command::SpawnActor::parent)
.def("then", &command_impl::Then, (arg("command")))
;
class_<cr::Command::DestroyActor>("DestroyActor")
.def("__init__", &command_impl::CustomInit<ActorPtr>, (arg("actor")))
@ -103,6 +137,7 @@ void export_commands() {
.def_readwrite("enabled", &cr::Command::SetAutopilot::enabled)
;
implicitly_convertible<cr::Command::SpawnActor, cr::Command>();
implicitly_convertible<cr::Command::DestroyActor, cr::Command>();
implicitly_convertible<cr::Command::ApplyVehicleControl, cr::Command>();
implicitly_convertible<cr::Command::ApplyWalkerControl, cr::Command>();

View File

@ -776,16 +776,31 @@ void FTheNewCarlaServer::FPimpl::BindActions()
using C = cr::Command;
auto command_visitor = carla::MakeOverload(
[=](const C::DestroyActor &c) { destroy_actor(c.actor); },
[=](const C::ApplyVehicleControl &c) { apply_control_to_vehicle(c.actor, c.control); },
[=](const C::ApplyWalkerControl &c) { apply_control_to_walker(c.actor, c.control); },
[=](const C::ApplyTransform &c) { set_actor_transform(c.actor, c.transform); },
[=](const C::ApplyVelocity &c) { set_actor_velocity(c.actor, c.velocity); },
[=](const C::ApplyAngularVelocity &c) { set_actor_angular_velocity(c.actor, c.angular_velocity); },
[=](const C::ApplyImpulse &c) { add_actor_impulse(c.actor, c.impulse); },
[=](const C::SetSimulatePhysics &c) { set_actor_simulate_physics(c.actor, c.enabled); },
[=](const C::SetAutopilot &c) { set_actor_autopilot(c.actor, c.enabled); },
auto command_visitor = carla::MakeRecursiveOverload(
[=](auto self, const C::SpawnActor &c) -> void {
auto result = c.parent.has_value() ?
spawn_actor_with_parent(c.description, c.transform, *c.parent) :
spawn_actor(c.description, c.transform);
if (!result.HasError()) {
carla::ActorId id = result.Get().id;
auto set_id = carla::MakeOverload(
[](C::SpawnActor &) {},
[id](auto &s) { s.actor = id; });
for (auto command : c.do_after) {
boost::apply_visitor(set_id, command.command);
boost::apply_visitor(self, command.command);
}
}
},
[=](auto, const C::DestroyActor &c) { destroy_actor(c.actor); },
[=](auto, const C::ApplyVehicleControl &c) { apply_control_to_vehicle(c.actor, c.control); },
[=](auto, const C::ApplyWalkerControl &c) { apply_control_to_walker(c.actor, c.control); },
[=](auto, const C::ApplyTransform &c) { set_actor_transform(c.actor, c.transform); },
[=](auto, const C::ApplyVelocity &c) { set_actor_velocity(c.actor, c.velocity); },
[=](auto, const C::ApplyAngularVelocity &c) { set_actor_angular_velocity(c.actor, c.angular_velocity); },
[=](auto, const C::ApplyImpulse &c) { add_actor_impulse(c.actor, c.impulse); },
[=](auto, const C::SetSimulatePhysics &c) { set_actor_simulate_physics(c.actor, c.enabled); },
[=](auto, const C::SetAutopilot &c) { set_actor_autopilot(c.actor, c.enabled); },
[](const auto &) { UE_LOG(LogCarla, Fatal, TEXT("Invalid command!")); });
BIND_SYNC(apply_batch) << [=](const std::vector<cr::Command> &commands, bool do_tick_cue) -> R<void>