'function-style casts in UE4
consider this code from a library file:
#pragma once
#include "carla/MsgPack.h"
#ifdef LIBCARLA_INCLUDED_FROM_UE4
#include "Carla/Vehicle/VehicleControl.h"
#endif // LIBCARLA_INCLUDED_FROM_UE4
namespace carla {
namespace rpc {
class VehicleControl {
public:
VehicleControl() = default;
VehicleControl(
float in_throttle,
float in_steer,
float in_brake,
bool in_hand_brake,
bool in_reverse,
bool in_manual_gear_shift,
int32_t in_gear)
: throttle(in_throttle),
steer(in_steer),
brake(in_brake),
hand_brake(in_hand_brake),
reverse(in_reverse),
manual_gear_shift(in_manual_gear_shift),
gear(in_gear) {}
float throttle = 0.0f;
float steer = 0.0f;
float brake = 0.0f;
bool hand_brake = false;
bool reverse = false;
bool manual_gear_shift = false;
int32_t gear = 0;
#ifdef LIBCARLA_INCLUDED_FROM_UE4
VehicleControl(const FVehicleControl &Control)
: throttle(Control.Throttle),
steer(Control.Steer),
brake(Control.Brake),
hand_brake(Control.bHandBrake),
reverse(Control.bReverse),
manual_gear_shift(Control.bManualGearShift),
gear(Control.Gear) {}
operator FVehicleControl() const {
FVehicleControl Control;
Control.Throttle = throttle;
Control.Steer = steer;
Control.Brake = brake;
Control.bHandBrake = hand_brake;
Control.bReverse = reverse;
Control.bManualGearShift = manual_gear_shift;
Control.Gear = gear;
return Control;
}
#endif // LIBCARLA_INCLUDED_FROM_UE4
bool operator!=(const VehicleControl &rhs) const {
return
throttle != rhs.throttle ||
steer != rhs.steer ||
brake != rhs.brake ||
hand_brake != rhs.hand_brake ||
reverse != rhs.reverse ||
manual_gear_shift != rhs.manual_gear_shift ||
gear != rhs.gear;
}
bool operator==(const VehicleControl &rhs) const {
return !(*this != rhs);
}
MSGPACK_DEFINE_ARRAY(
throttle,
steer,
brake,
hand_brake,
reverse,
manual_gear_shift,
gear);
};
} // namespace rpc
} // namespace carla
that is included in this cpp file:
#include "Carla.h"
#include "Carla/Sensor/WorldObserver.h"
#include "Carla/Actor/ActorData.h"
#include "Carla/Actor/ActorRegistry.h"
#include "Carla/Game/CarlaEpisode.h"
#include "Carla/Traffic/TrafficLightBase.h"
#include "Carla/Traffic/TrafficLightComponent.h"
#include "Carla/Traffic/TrafficLightController.h"
#include "Carla/Traffic/TrafficLightGroup.h"
#include "Carla/Traffic/TrafficSignBase.h"
#include "Carla/Traffic/SignComponent.h"
#include "Carla/Walker/WalkerController.h"
#include "CoreGlobals.h"
#include <compiler/disable-ue4-macros.h>
#include <carla/rpc/String.h>
#include <carla/sensor/SensorRegistry.h>
#include <carla/sensor/data/ActorDynamicState.h>
#include <carla/rpc/VehicleControl.h>
#include <carla/rpc/WalkerControl.h>
#include <compiler/enable-ue4-macros.h>
static auto FWorldObserver_GetActorState(const FCarlaActor &View, const FActorRegistry &Registry)
{
using AType = FCarlaActor::ActorType;
carla::sensor::data::ActorDynamicState::TypeDependentState state{};
if (AType::Vehicle == View.GetActorType())
{
auto Vehicle = Cast<ACarlaWheeledVehicle>(View.GetActor());
if (Vehicle != nullptr)
{
state.vehicle_data.control = carla::rpc::VehicleControl{Vehicle->GetVehicleControl()};
auto Controller = Cast<AWheeledVehicleAIController>(Vehicle->GetController());
if (Controller != nullptr)
{
using TLS = carla::rpc::TrafficLightState;
state.vehicle_data.traffic_light_state = static_cast<TLS>(Controller->GetTrafficLightState());
state.vehicle_data.speed_limit = Controller->GetSpeedLimit();
auto TrafficLight = Controller->GetTrafficLight();
if (TrafficLight != nullptr)
{
state.vehicle_data.has_traffic_light = true;
auto* TrafficLightView = Registry.FindCarlaActor(TrafficLight);
if(TrafficLightView)
{
state.vehicle_data.traffic_light_id = TrafficLightView->GetActorId();
}
else
{
state.vehicle_data.has_traffic_light = false;
}
}
else
{
state.vehicle_data.has_traffic_light = false;
}
}
}
}
else if (AType::Walker == View.GetActorType())
{
auto Walker = Cast<APawn>(View.GetActor());
auto Controller = Walker != nullptr ? Cast<AWalkerController>(Walker->GetController()) : nullptr;
if (Controller != nullptr)
{
state.walker_control = carla::rpc::WalkerControl{Controller->GetWalkerControl()};
}
}
else if (AType::TrafficLight == View.GetActorType())
{
auto TrafficLight = Cast<ATrafficLightBase>(View.GetActor());
if (TrafficLight != nullptr)
{
auto* TrafficLightComponent =
TrafficLight->GetTrafficLightComponent();
using TLS = carla::rpc::TrafficLightState;
if(TrafficLightComponent == nullptr)
{
// Old way: traffic lights are actors
state.traffic_light_data.sign_id[0] = '\0';
state.traffic_light_data.state = static_cast<TLS>(TrafficLight->GetTrafficLightState());
state.traffic_light_data.green_time = TrafficLight->GetGreenTime();
state.traffic_light_data.yellow_time = TrafficLight->GetYellowTime();
state.traffic_light_data.red_time = TrafficLight->GetRedTime();
state.traffic_light_data.elapsed_time = TrafficLight->GetElapsedTime();
state.traffic_light_data.time_is_frozen = TrafficLight->GetTimeIsFrozen();
state.traffic_light_data.pole_index = TrafficLight->GetPoleIndex();
}
else
{
const UTrafficLightController* Controller = TrafficLightComponent->GetController();
const ATrafficLightGroup* Group = TrafficLightComponent->GetGroup();
if (!Controller)
{
UE_LOG(LogCarla, Error, TEXT("TrafficLightComponent doesn't have any Controller assigned"));
}
else if (!Group)
{
UE_LOG(LogCarla, Error, TEXT("TrafficLightComponent doesn't have any Group assigned"));
}
else
{
const FString fstring_sign_id = TrafficLightComponent->GetSignId();
const std::string sign_id = carla::rpc::FromFString(fstring_sign_id);
constexpr size_t max_size = sizeof(state.traffic_light_data.sign_id);
size_t sign_id_length = sign_id.length();
if(max_size < sign_id_length)
{
UE_LOG(LogCarla, Warning, TEXT("The max size of a signal id is 32. %s (%d)"), *fstring_sign_id, sign_id.length());
sign_id_length = max_size;
}
std::memset(state.traffic_light_data.sign_id, '\0', max_size);
std::memcpy(state.traffic_light_data.sign_id, sign_id.c_str(), sign_id_length);
state.traffic_light_data.state = static_cast<TLS>(TrafficLightComponent->GetLightState());
state.traffic_light_data.green_time = Controller->GetGreenTime();
state.traffic_light_data.yellow_time = Controller->GetYellowTime();
state.traffic_light_data.red_time = Controller->GetRedTime();
state.traffic_light_data.elapsed_time = Controller->GetElapsedTime();
state.traffic_light_data.time_is_frozen = Group->IsFrozen();
state.traffic_light_data.pole_index = TrafficLight->GetPoleIndex();
}
}
}
}
else if (AType::TrafficSign == View.GetActorType())
{
auto TrafficSign = Cast<ATrafficSignBase>(View.GetActor());
if (TrafficSign != nullptr)
{
USignComponent* TrafficSignComponent =
Cast<USignComponent>(TrafficSign->FindComponentByClass<USignComponent>());
if(TrafficSignComponent)
{
const FString fstring_sign_id = TrafficSignComponent->GetSignId();
const std::string sign_id = carla::rpc::FromFString(fstring_sign_id);
constexpr size_t max_size = sizeof(state.traffic_sign_data.sign_id);
size_t sign_id_length = sign_id.length();
if(max_size < sign_id_length)
{
UE_LOG(LogCarla, Warning, TEXT("The max size of a signal id is 32. %s (%d)"), *fstring_sign_id, sign_id.length());
sign_id_length = max_size;
}
std::memset(state.traffic_light_data.sign_id, '\0', max_size);
std::memcpy(state.traffic_sign_data.sign_id, sign_id.c_str(), sign_id_length);
}
}
}
return state;
}
Do you have any idea, how the code
state.vehicle_data.control = carla::rpc::VehicleControl{Vehicle->GetVehicleControl()};
would throw compiler error 2440?
D:/carla/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/WorldObserver.cpp(42): error C2440: "<function-style-cast>": "initializer list" kann nicht in "carla::rpc::VehicleControl" konvertiert werden
The respective constructor is defined and should be included, as LIBCARLA_INCLUDED_BY_UE4 is defined in <compiler/disable-ue4-macros.h>, before the library file is included.
Any suggestions? I can't see where the error would be.
Solution 1:[1]
Turned out that I had to move my library includes to the top of the .cpp-File, or carla::rpc::VehicleControl and carla::rpc::WalkerControl wouldn't be known to the compiler early enough, which would lead to the error with the function-style cast.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | roque2205 |