Plugin refactoring to sync with AirLib (Part 2)

This commit is contained in:
Shital Shah 2018-06-03 03:27:24 -07:00
Родитель 78983c7d12
Коммит a6f365f517
37 изменённых файлов: 519 добавлений и 332 удалений

Просмотреть файл

@ -50,6 +50,7 @@
<ClInclude Include="include\common\common_utils\ProsumerQueue.hpp" />
<ClInclude Include="include\common\common_utils\RandomGenerator.hpp" />
<ClInclude Include="include\common\common_utils\ScheduledExecutor.hpp" />
<ClInclude Include="include\common\common_utils\Signal.hpp" />
<ClInclude Include="include\common\common_utils\sincos.hpp" />
<ClInclude Include="include\common\common_utils\StrictMode.hpp" />
<ClInclude Include="include\common\common_utils\Timer.hpp" />

Просмотреть файл

@ -429,6 +429,9 @@
<ClInclude Include="include\api\ApiProvider.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\common\common_utils\Signal.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\safety\ObstacleMap.cpp">

Просмотреть файл

@ -53,11 +53,23 @@ public:
{
return vehicle_apis_;
}
const std::map<std::string, VehicleSimApiBase*>& getVehicleSimApis()
const std::map<std::string, VehicleSimApiBase*>& geVehicleSimApis()
{
return vehicle_sim_apis_;
}
bool hasDefaultVehicle() const
{
return Utils::findOrDefault<std::string, VehicleApiBase*>(vehicle_apis_, "") == nullptr &&
Utils::findOrDefault<std::string, VehicleSimApiBase*>(vehicle_sim_apis_, "") == nullptr;
}
void makeDefaultVehicle(const std::string& vehicle_name)
{
vehicle_apis_[""] = vehicle_apis_[vehicle_name];
vehicle_sim_apis_[""] = vehicle_sim_apis_[vehicle_name];
}
private:
WorldSimApiBase* world_sim_api_;

Просмотреть файл

@ -264,19 +264,19 @@ public:
};
struct ImageRequest {
uint8_t camera_id;
std::string camera_name;
msr::airlib::ImageCaptureBase::ImageType image_type;
bool pixels_as_float;
bool compress;
MSGPACK_DEFINE_MAP(camera_id, image_type, pixels_as_float, compress);
MSGPACK_DEFINE_MAP(camera_name, image_type, pixels_as_float, compress);
ImageRequest()
{}
ImageRequest(const msr::airlib::ImageCaptureBase::ImageRequest& s)
{
camera_id = s.camera_id;
camera_name = s.camera_name;
image_type = s.image_type;
pixels_as_float = s.pixels_as_float;
compress = s.compress;
@ -285,7 +285,7 @@ public:
msr::airlib::ImageCaptureBase::ImageRequest to() const
{
msr::airlib::ImageCaptureBase::ImageRequest d;
d.camera_id = camera_id;
d.camera_name = camera_name;
d.image_type = image_type;
d.pixels_as_float = pixels_as_float;
d.compress = compress;

Просмотреть файл

@ -45,7 +45,7 @@ public:
Pose simGetObjectPose(const std::string& object_name) const;
vector<ImageCaptureBase::ImageResponse> simGetImages(vector<ImageCaptureBase::ImageRequest> request);
vector<uint8_t> simGetImage(int camera_id, ImageCaptureBase::ImageType type);
vector<uint8_t> simGetImage(const std::string& camera_name, ImageCaptureBase::ImageType type);
CollisionInfo simGetCollisionInfo() const;
@ -53,8 +53,8 @@ public:
int simGetSegmentationObjectID(const std::string& mesh_name) const;
void simPrintLogMessage(const std::string& message, std::string message_param = "", unsigned char severity = 0);
CameraInfo simGetCameraInfo(int camera_id) const;
void simSetCameraOrientation(int camera_id, const Quaternionr& orientation);
CameraInfo simGetCameraInfo(const std::string& camera_name) const;
void simSetCameraOrientation(const std::string& camera_name, const Quaternionr& orientation);
//task management APIs
void cancelLastTask();

Просмотреть файл

@ -50,10 +50,13 @@ public:
virtual RCData getRCData() const = 0; //get reading from RC from simulator
virtual std::string getVehicleName() const = 0;
virtual std::string getLogLine() const = 0;
virtual void setLogLine(std::string line) = 0;
virtual void toggleTrace() = 0;
const AirSimSettings::VehicleSetting& getVehicleSetting() const
//use pointer here because of derived classes for VehicleSetting
const AirSimSettings::VehicleSetting* getVehicleSetting() const
{
return *(AirSimSettings::singleton().getVehicleSetting(getVehicleName()));
return AirSimSettings::singleton().getVehicleSetting(getVehicleName());
}
};

Просмотреть файл

@ -31,10 +31,10 @@ public: //types
int window_index;
ImageType image_type;
bool visible;
int camera_id;
std::string camera_name;
SubwindowSetting(int window_index_val = 0, ImageType image_type_val = ImageType::Scene, bool visible_val = false, int camera_id_val = 0)
: window_index(window_index_val), image_type(image_type_val), visible(visible_val), camera_id(camera_id_val)
SubwindowSetting(int window_index_val = 0, ImageType image_type_val = ImageType::Scene, bool visible_val = false, const std::string& camera_name_val = 0)
: window_index(window_index_val), image_type(image_type_val), visible(visible_val), camera_name(camera_name_val)
{
}
};
@ -848,7 +848,7 @@ private:
subwindow_setting.image_type = Utils::toEnum<ImageType>(
json_settings_child.getInt("ImageType", 0));
subwindow_setting.visible = json_settings_child.getBool("Visible", false);
subwindow_setting.camera_id = json_settings_child.getInt("CameraID", 0);
subwindow_setting.camera_name = json_settings_child.getString("CameraName", "");
}
}
}

Просмотреть файл

@ -13,7 +13,7 @@ namespace msr { namespace airlib {
class ImageCaptureBase
{
public: //types
enum class ImageType : uint { //this indexes to array
enum class ImageType : int { //this indexes to array, -1 is special to indicate main camera
Scene = 0,
DepthPlanner,
DepthPerspective,

Просмотреть файл

@ -0,0 +1,101 @@
#ifndef common_utils_Signal_hpp
#define common_utils_Signal_hpp
#include <functional>
#include <map>
// A signal object may call multiple slots with the
// same signature. You can connect functions to the signal
// which will be called when the emit() method on the
// signal object is invoked. Any argument passed to emit()
// will be passed to the given functions.
/*
//USAGE:
#include "Signal.hpp"
#include <iostream>
int main() {
// create new signal
Signal<std::string, int> signal;
// attach a slot
signal.connect([](std::string arg1, int arg2) {
std::cout << arg1 << " " << arg2 << std::endl;
});
signal.emit("The answer:", 42);
return 0;
}
*/
namespace common_utils {
template <typename... Args>
class Signal {
public:
Signal() : current_id_(0) {}
// copy creates new signal
Signal(Signal const& other) : current_id_(0) {}
// connects a member function to this Signal
template <typename T>
int connect_member(T *inst, void (T::*func)(Args...)) {
return connect([=](Args... args) {
(inst->*func)(args...);
});
}
// connects a const member function to this Signal
template <typename T>
int connect_member(T *inst, void (T::*func)(Args...) const) {
return connect([=](Args... args) {
(inst->*func)(args...);
});
}
// connects a std::function to the signal. The returned
// value can be used to disconnect the function again
int connect(std::function<void(Args...)> const& slot) const {
slots_.insert(std::make_pair(++current_id_, slot));
return current_id_;
}
// disconnects a previously connected function
void disconnect(int id) const {
slots_.erase(id);
}
// disconnects all previously connected functions
void disconnect_all() const {
slots_.clear();
}
// calls all connected functions
void emit(Args... p) {
for (auto it : slots_) {
it.second(p...);
}
}
// assignment creates new Signal
Signal& operator=(Signal const& other) {
disconnect_all();
}
private:
mutable std::map<int, std::function<void(Args...)>> slots_;
mutable int current_id_;
};
}
#endif /* common_utils_Signal_hpp */

Просмотреть файл

@ -127,13 +127,21 @@ public:
}
template <template<class, class, class...> class TContainer, typename TKey, typename TVal, typename... Args>
static TVal findOrDefault(const TContainer<TKey, TVal, Args...>& m, TKey const& key, const TVal & default_val)
static TVal findOrDefault(const TContainer<TKey, TVal, Args...>& m, TKey const& key, const TVal& default_val)
{
typename TContainer<TKey, TVal, Args...>::const_iterator it = m.find(key);
if (it == m.end())
return default_val;
return it->second;
}
template <typename TKey, typename TVal>
static TVal findOrDefault(const std::map<TKey, TVal>& m, TKey const& key, const TVal& default_val = TVal())
{
typename TContainer<TKey, TVal>::const_iterator it = m.find(key);
if (it == m.end())
return default_val;
return it->second;
}
static Logger* getSetLogger(Logger* logger = nullptr)
{

Просмотреть файл

@ -28,7 +28,7 @@ public:
SimpleFlightApi(const MultiRotorParams* vehicle_params, const AirSimSettings::VehicleSetting* vehicle_setting)
: vehicle_params_(vehicle_params)
{
readSettings(vehicle_setting);
readSettings(*vehicle_setting);
//TODO: set below properly for better high speed safety
safety_params_.vel_to_breaking_dist = safety_params_.min_breaking_dist = 0;
@ -127,6 +127,8 @@ public: //MultirotorApiBase implementation
else { //else we don't have RC data
board_->setIsRcConnected(false);
}
return true;
}
protected:
@ -280,14 +282,14 @@ private:
return static_cast<uint16_t>(1000.0f * switchVal / maxSwitchVal + 1000.0f);
}
void readSettings(const AirSimSettings::VehicleSetting* vehicle_setting)
void readSettings(const AirSimSettings::VehicleSetting& vehicle_setting)
{
params_.default_vehicle_state = simple_flight::VehicleState::fromString(
vehicle_setting->default_vehicle_state == "" ? "Armed" : vehicle_setting->default_vehicle_state);
vehicle_setting.default_vehicle_state == "" ? "Armed" : vehicle_setting.default_vehicle_state);
remote_control_id_ = vehicle_setting->rc.remote_control_id;
params_.rc.allow_api_when_disconnected = vehicle_setting->rc.allow_api_when_disconnected;
params_.rc.allow_api_always = vehicle_setting->allow_api_always;
remote_control_id_ = vehicle_setting.rc.remote_control_id;
params_.rc.allow_api_when_disconnected = vehicle_setting.rc.allow_api_when_disconnected;
params_.rc.allow_api_always = vehicle_setting.allow_api_always;
}
private:

Просмотреть файл

@ -68,7 +68,7 @@ protected:
private:
vector<unique_ptr<SensorBase>> sensor_storage_;
const AirSimSettings::VehicleSetting* vehicle_setting_;
const AirSimSettings::VehicleSetting* vehicle_setting_; //store as pointer because of derived classes
std::shared_ptr<const SensorFactory> sensor_factory_;
};

Просмотреть файл

@ -179,9 +179,9 @@ vector<ImageCaptureBase::ImageResponse> RpcLibClientBase::simGetImages(vector<Im
return RpcLibAdapatorsBase::ImageResponse::to(response_adaptor);
}
vector<uint8_t> RpcLibClientBase::simGetImage(int camera_id, ImageCaptureBase::ImageType type)
vector<uint8_t> RpcLibClientBase::simGetImage(const std::string& camera_name, ImageCaptureBase::ImageType type)
{
vector<uint8_t> result = pimpl_->client.call("simGetImage", camera_id, type).as<vector<uint8_t>>();
vector<uint8_t> result = pimpl_->client.call("simGetImage", camera_name, type).as<vector<uint8_t>>();
if (result.size() == 1) {
// rpclib has a bug with serializing empty vectors, so we return a 1 byte vector instead.
result.clear();
@ -214,13 +214,13 @@ msr::airlib::Pose RpcLibClientBase::simGetObjectPose(const std::string& object_n
return pimpl_->client.call("simGetObjectPose", object_name).as<RpcLibAdapatorsBase::Pose>().to();
}
CameraInfo RpcLibClientBase::simGetCameraInfo(int camera_id) const
CameraInfo RpcLibClientBase::simGetCameraInfo(const std::string& camera_name) const
{
return pimpl_->client.call("simGetCameraInfo", camera_id).as<RpcLibAdapatorsBase::CameraInfo>().to();
return pimpl_->client.call("simGetCameraInfo", camera_name).as<RpcLibAdapatorsBase::CameraInfo>().to();
}
void RpcLibClientBase::simSetCameraOrientation(int camera_id, const Quaternionr& orientation)
void RpcLibClientBase::simSetCameraOrientation(const std::string& camera_name, const Quaternionr& orientation)
{
pimpl_->client.call("simSetCameraOrientation", camera_id, RpcLibAdapatorsBase::Quaternionr(orientation));
pimpl_->client.call("simSetCameraOrientation", camera_name, RpcLibAdapatorsBase::Quaternionr(orientation));
}
void RpcLibClientBase::cancelLastTask()

Просмотреть файл

@ -81,8 +81,8 @@ RpcLibServerBase::RpcLibServerBase(ApiProvider* api_provider, const std::string&
const auto& response = getVehicleSimApi()->getImages(RpcLibAdapatorsBase::ImageRequest::to(request_adapter));
return RpcLibAdapatorsBase::ImageResponse::from(response);
});
pimpl_->server.bind("simGetImage", [&](uint8_t camera_id, ImageCaptureBase::ImageType type) -> vector<uint8_t> {
auto result = getVehicleSimApi()->getImage(camera_id, type);
pimpl_->server.bind("simGetImage", [&](const std::string& camera_name, ImageCaptureBase::ImageType type) -> vector<uint8_t> {
auto result = getVehicleSimApi()->getImage(camera_name, type);
if (result.size() == 0) {
// rpclib has a bug with serializing empty vectors, so we return a 1 byte vector instead.
result.push_back(0);
@ -125,13 +125,13 @@ RpcLibServerBase::RpcLibServerBase(ApiProvider* api_provider, const std::string&
return RpcLibAdapatorsBase::GeoPoint(geo_point);
});
pimpl_->server.bind("simGetCameraInfo", [&](int camera_id) -> RpcLibAdapatorsBase::CameraInfo {
const auto& camera_info = getVehicleSimApi()->getCameraInfo(camera_id);
pimpl_->server.bind("simGetCameraInfo", [&](const std::string& camera_name) -> RpcLibAdapatorsBase::CameraInfo {
const auto& camera_info = getVehicleSimApi()->getCameraInfo(camera_name);
return RpcLibAdapatorsBase::CameraInfo(camera_info);
});
pimpl_->server.bind("simSetCameraOrientation", [&](int camera_id, const RpcLibAdapatorsBase::Quaternionr& orientation) -> void {
getVehicleSimApi()->setCameraOrientation(camera_id, orientation.to());
pimpl_->server.bind("simSetCameraOrientation", [&](const std::string& camera_name, const RpcLibAdapatorsBase::Quaternionr& orientation) -> void {
getVehicleSimApi()->setCameraOrientation(camera_name, orientation.to());
});
pimpl_->server.bind("simGetCollisionInfo", [&]() -> RpcLibAdapatorsBase::CollisionInfo {

Просмотреть файл

@ -28,9 +28,7 @@ public:
std::make_shared<SensorFactory>());
auto api = params->createMultirotorApi();
std::unique_ptr<Environment> environment;
MultiRotor vehicle(params.get(), api.get(), Pose(),
GeoPoint(), environment);
MultiRotor vehicle(params.get(), api.get(), Pose());
std::vector<UpdatableObject*> vehicles = { &vehicle };
std::unique_ptr<PhysicsEngineBase> physics_engine(new FastPhysicsEngine());

Просмотреть файл

@ -81,7 +81,7 @@ int main(int argc, const char* argv[])
ApiProvider api_provider(nullptr);
api_provider.insert_or_assign("", &api);
api_provider.insert_or_assign("", &api, nullptr);
msr::airlib::MultirotorRpcLibServer server(&api_provider, connection_info.local_host_ip);
//start server in async mode

Просмотреть файл

@ -61,9 +61,9 @@ public:
auto start_nanos = clock->nowNanos();
std::vector<ImageRequest> request = {
ImageRequest(0, ImageType::Scene),
ImageRequest(1, ImageType::Scene),
ImageRequest(1, ImageType::DisparityNormalized, true)
ImageRequest("0", ImageType::Scene),
ImageRequest("1", ImageType::Scene),
ImageRequest("1", ImageType::DisparityNormalized, true)
};
const std::vector<ImageResponse>& response = client.simGetImages(request);
if (response.size() != 3) {

Просмотреть файл

@ -34,9 +34,9 @@ int main()
client.confirmConnection();
std::cout << "Press Enter to get FPV image" << std::endl; std::cin.get();
vector<ImageRequest> request = { ImageRequest(0, ImageType::Scene), ImageRequest(1, ImageType::DepthPlanner, true) };
vector<ImageRequest> request = { ImageRequest("0", ImageType::Scene), ImageRequest("1", ImageType::DepthPlanner, true) };
const vector<ImageResponse>& response = client.simGetImages(request);
std::cout << "# of images recieved: " << response.size() << std::endl;
std::cout << "# of images received: " << response.size() << std::endl;
if (response.size() > 0) {
std::cout << "Enter path with ending separator to save images (leave empty for no save)" << std::endl;

Просмотреть файл

@ -30,9 +30,9 @@ int main()
client.confirmConnection();
std::cout << "Press Enter to get FPV image" << std::endl; std::cin.get();
vector<ImageRequest> request = { ImageRequest(0, ImageType::Scene), ImageRequest(1, ImageType::DepthPlanner, true) };
vector<ImageRequest> request = { ImageRequest("0", ImageType::Scene), ImageRequest("1", ImageType::DepthPlanner, true) };
const vector<ImageResponse>& response = client.simGetImages(request);
std::cout << "# of images recieved: " << response.size() << std::endl;
std::cout << "# of images received: " << response.size() << std::endl;
if (response.size() > 0) {
std::cout << "Enter path with ending separator to save images (leave empty for no save)" << std::endl;

Просмотреть файл

@ -107,7 +107,7 @@ public:
void onHandbrakePressed();
/** Handle handbrake released */
void onHandbrakeReleased();
/** Handle pressiong footbrake */
/** Handle processing footbrake */
void FootBrake(float Val);
/** Handle Reverse pressed */
void onReversePressed();
@ -115,7 +115,7 @@ public:
void onReverseReleased();
/** Handle Handbrake pressed */
/** Setup the strings used on the hud */
/** Setup the strings used on the HUD */
void updateInCarHUD();
/** update the physics material used by the vehicle mesh */
@ -137,7 +137,7 @@ private:
UClass* pip_camera_class_;
VehicleSimApiBase* vehicle_sim_api_;
msr::airlib::VehicleSimApiBase* vehicle_sim_api_;
msr::airlib::Kinematics::State kinematics_;
CarPawnApi::CarControls keyboard_controls_;

Просмотреть файл

@ -95,7 +95,7 @@ void ASimModeCar::setupClockSpeed()
UAirBlueprintLib::LogMessageString("Clock Speed: ", std::to_string(current_clockspeed_), LogDebugLevel::Informational);
}
void ASimModeCar::setupVehiclesAndCamera(std::vector<VehiclePtr>& vehicles)
void ASimModeCar::setupVehiclesAndCamera(std::vector<TVehiclePawn*>& vehicles)
{
//get player controller
APlayerController* player_controller = this->GetWorld()->GetFirstPlayerController();
@ -204,7 +204,7 @@ int ASimModeCar::getRemoteControlID(const VehicleSimApi& pawn) const
return fpv_vehicle_sim_api_->getRemoteControlID();
}
void ASimModeCar::createVehicles(std::vector<VehiclePtr>& vehicles)
void ASimModeCar::createVehicles(std::vector<TVehiclePawn*>& vehicles)
{
//find vehicles and cameras available in environment
//if none available then we will create one
@ -247,7 +247,7 @@ void ASimModeCar::Tick(float DeltaSeconds)
void ASimModeCar::updateDebugReport()
{
for (VehiclePtr vehicle : vehicles_) {
for (TVehiclePawn* vehicle : vehicles_) {
VehicleSimApi* vehicle_sim_api = vehicle->getVehicleSimApi();
msr::airlib::StateReporter& reporter = *debug_reporter_.getReporter();
std::string vehicle_name = fpv_vehicle_sim_api_->getVehicleSetting()->vehicle_name;

Просмотреть файл

@ -16,9 +16,6 @@ class AIRSIM_API ASimModeCar : public ASimModeBase
GENERATED_BODY()
public:
typedef ACarPawn* VehiclePtr;
typedef ACarPawn TVehiclePawn;
ASimModeCar();
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
@ -32,28 +29,31 @@ public:
virtual void continueForTime(double seconds) override;
private:
void setupVehiclesAndCamera(std::vector<VehiclePtr>& vehicles);
void updateDebugReport();
int getRemoteControlID(const VehicleSimApi& pawn) const;
void initializePauseState();
protected:
virtual void setupClockSpeed() override;
virtual std::unique_ptr<msr::airlib::ApiServerBase> createApiServer() const override;
virtual void createVehicles(std::vector<VehiclePtr>& vehicles);
private:
typedef msr::airlib::ClockFactory ClockFactory;
typedef common_utils::Utils Utils;
typedef msr::airlib::TTimePoint TTimePoint;
typedef msr::airlib::TTimeDelta TTimeDelta;
typedef ACarPawn TVehiclePawn;
private:
void setupVehiclesAndCamera(std::vector<TVehiclePawn*>& vehicles);
void updateDebugReport();
int getRemoteControlID(const VehicleSimApi& pawn) const;
void initializePauseState();
void createVehicles(std::vector<TVehiclePawn*>& vehicles);
protected:
virtual void setupClockSpeed() override;
virtual std::unique_ptr<msr::airlib::ApiServerBase> createApiServer() const override;
private:
UClass* external_camera_class_;
UClass* camera_director_class_;
TArray<AActor*> spawned_actors_;
std::vector<VehiclePtr> vehicles_;
VehicleSimApiBase* fpv_vehicle_sim_api_;
UPROPERTY()
TArray<AActor*> spawned_actors_; //keep refs alive from Unreal GC
std::vector<TVehiclePawn*> vehicles_;
float follow_distance_;
msr::airlib::StateReporterWrapper debug_reporter_;

Просмотреть файл

@ -1,33 +1,21 @@
#include "FlyingPawn.h"
#include "Components/StaticMeshComponent.h"
#include "Engine/World.h"
#include "AirBlueprintLib.h"
#include "common/CommonStructs.hpp"
#include "common/Common.hpp"
#include "VehicleSimApi.h"
AFlyingPawn::AFlyingPawn()
{
static ConstructorHelpers::FClassFinder<APIPCamera> pip_camera_class(TEXT("Blueprint'/AirSim/Blueprints/BP_PIPCamera'"));
pip_camera_class_ = pip_camera_class.Succeeded() ? pip_camera_class.Class : nullptr;
}
void AFlyingPawn::BeginPlay()
{
Super::BeginPlay();
}
void AFlyingPawn::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
vehicle_sim_api_.reset();
cameras_.clear();
Super::EndPlay(EndPlayReason);
for (auto i = 0; i < rotor_count; ++i) {
rotating_movements_[i] = UAirBlueprintLib::GetActorComponent<URotatingMovementComponent>(this, TEXT("Rotation") + FString::FromInt(i));
}
}
void AFlyingPawn::initializeForBeginPlay(const NedTransform& global_transform, const std::string& vehicle_name)
{
cameras_.clear();
vehicle_sim_api_.reset(new VehicleSimApi(this, &cameras_, global_transform, vehicle_name));
void AFlyingPawn::initializeForBeginPlay()
{
//get references of existing camera
fpv_camera_front_right_ = Cast<APIPCamera>(
(UAirBlueprintLib::GetActorComponent<UChildActorComponent>(this, TEXT("FrontRightCamera")))->GetChildActor());
@ -39,46 +27,36 @@ void AFlyingPawn::initializeForBeginPlay(const NedTransform& global_transform, c
(UAirBlueprintLib::GetActorComponent<UChildActorComponent>(this, TEXT("BackCenterCamera")))->GetChildActor());
fpv_camera_bottom_center_ = Cast<APIPCamera>(
(UAirBlueprintLib::GetActorComponent<UChildActorComponent>(this, TEXT("BottomCenterCamera")))->GetChildActor());
}
cameras_["0"] = cameras_["front_center"] = fpv_camera_front_center_;
cameras_["1"] = cameras_["front_right"] = fpv_camera_front_right_;
cameras_["2"] = cameras_["front_left"] = fpv_camera_front_left_;
cameras_["3"] = cameras_["bottom_center"] = fpv_camera_bottom_center_;
cameras_["4"] = cameras_["back_center"] = fpv_camera_back_center_;
//UStaticMeshComponent* bodyMesh = UAirBlueprintLib::GetActorComponent<UStaticMeshComponent>(this, TEXT("BodyMesh"));
USceneComponent* bodyMesh = GetRootComponent();
FActorSpawnParameters camera_spawn_params;
camera_spawn_params.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
void AFlyingPawn::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
fpv_camera_front_right_ = nullptr;
fpv_camera_front_left_ = nullptr;
fpv_camera_front_center_ = nullptr;
fpv_camera_back_center_ = nullptr;
fpv_camera_bottom_center_ = nullptr;
const auto& transform = vehicle_sim_api_->getNedTransform();
for (const auto& camera_setting_pair : vehicle_sim_api_->getVehicleSettings().cameras) {
const auto& setting = camera_setting_pair.second;
Super::EndPlay(EndPlayReason);
}
FVector position = transform.fromLocalNed(
NedTransform::Vector3r(setting.position.x, setting.position.y, setting.position.z))
- transform.fromLocalNed(NedTransform::Vector3r(0.0, 0.0, 0.0));
std::map<std::string, APIPCamera*> AFlyingPawn::getCameras() const
{
std::map<std::string, APIPCamera*> cameras;
FTransform camera_transform(FRotator(setting.rotation.pitch, setting.rotation.yaw, setting.rotation.roll),
position, FVector(1., 1., 1.));
cameras["0"] = cameras["front_center"] = fpv_camera_front_center_;
cameras["1"] = cameras["front_right"] = fpv_camera_front_right_;
cameras["2"] = cameras["front_left"] = fpv_camera_front_left_;
cameras["3"] = cameras["bottom_center"] = fpv_camera_bottom_center_;
cameras["4"] = cameras["back_center"] = fpv_camera_back_center_;
APIPCamera* camera = this->GetWorld()->SpawnActor<APIPCamera>(pip_camera_class_, camera_transform, camera_spawn_params);
camera->AttachToComponent(bodyMesh, FAttachmentTransformRules::KeepRelativeTransform);
cameras_[camera_setting_pair.first] = camera;
}
for (auto i = 0; i < rotor_count; ++i) {
rotating_movements_[i] = UAirBlueprintLib::GetActorComponent<URotatingMovementComponent>(this, TEXT("Rotation") + FString::FromInt(i));
}
vehicle_sim_api_->setupCamerasFromSettings();
return cameras;
}
void AFlyingPawn::NotifyHit(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation,
FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit)
{
vehicle_sim_api_->onCollision(MyComp, Other, OtherComp, bSelfMoved, HitLocation,
collision_signal_.emit(MyComp, Other, OtherComp, bSelfMoved, HitLocation,
HitNormal, NormalImpulse, Hit);
}

Просмотреть файл

@ -1,11 +1,9 @@
#pragma once
#include "VehicleSimApi.h"
#include "GameFramework/RotatingMovementComponent.h"
#include <memory>
#include "vehicles/multirotor/api/MultirotorCommon.hpp"
#include "PIPCamera.h"
#include "api/VehicleSimApiBase.hpp"
#include "common/common_utils/Signal.hpp"
#include "FlyingPawn.generated.h"
UCLASS()
@ -14,28 +12,27 @@ class AIRSIM_API AFlyingPawn : public APawn
GENERATED_BODY()
public:
AFlyingPawn();
typedef common_utils::Signal<class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation,
FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit> CollisionSignal;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Debugging")
float RotatorFactor = 1.0f;
void setRotorSpeed(int rotor_index, float radsPerSec);
void initializeForBeginPlay(const NedTransform& global_transform, const std::string& vehicle_name);
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual void NotifyHit(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation,
FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit) override;
msr::airlib::VehicleSimApiBase* getVehicleSimApi()
{
return vehicle_sim_api_.get();
}
//interface
void initializeForBeginPlay();
std::map<std::string, APIPCamera*> getCameras() const;
CollisionSignal& getCollisionSignal();
//called by API to set rotor speed
void setRotorSpeed(int rotor_index, float radsPerSec);
private: //variables
UPROPERTY() UClass* pip_camera_class_;
//Unreal components
//Unreal components
static constexpr size_t rotor_count = 4;
UPROPERTY() APIPCamera* fpv_camera_front_left_;
UPROPERTY() APIPCamera* fpv_camera_front_right_;
@ -45,6 +42,5 @@ private: //variables
UPROPERTY() URotatingMovementComponent* rotating_movements_[rotor_count];
std::map<std::string, APIPCamera*> cameras_;
std::_Unique_ptr_base<msr::airlib::VehicleSimApiBase> vehicle_sim_api_;
CollisionSignal collision_signal_;
};

Просмотреть файл

@ -1,16 +1,16 @@
#include "MultirotorSimApi.h"
#include "FlyingPawn.h"
#include "AirBlueprintLib.h"
#include "vehicles/multirotor/MultiRotorParamsFactory.hpp"
#include "UnrealSensors/UnrealSensorFactory.h"
#include <exception>
using namespace msr::airlib;
MultirotorSimApi::MultirotorSimApi(msr::airlib::MultirotorApiBase* vehicle_api, msr::airlib::MultiRotorParams* vehicle_params,
UManualPoseController* manual_pose_controller,
APawn* pawn, const std::map<std::string, APIPCamera*>* cameras, const NedTransform& global_transform,
const std::string& vehicle_name)
: VehicleSimApi(pawn, cameras, global_transform, vehicle_name), vehicle_api_(vehicle_api),
vehicle_params_(vehicle_params), manual_pose_controller_(manual_pose_controller)
MultirotorSimApi::MultirotorSimApi(APawn* pawn, const NedTransform& global_transform, CollisionSignal& collision_signal,
const std::map<std::string, APIPCamera*>& cameras,
UManualPoseController* manual_pose_controller)
: VehicleSimApi(pawn, global_transform, collision_signal, cameras),
manual_pose_controller_(manual_pose_controller)
{
//reset roll & pitch of vehicle as multirotors required to be on plain surface at start
Pose pose = getPose();
@ -19,6 +19,8 @@ MultirotorSimApi::MultirotorSimApi(msr::airlib::MultirotorApiBase* vehicle_api,
pose.orientation = VectorMath::toQuaternion(0, 0, yaw);
setPose(pose, false);
createVehicleApi();
//setup physics vehicle
phys_vehicle_ = std::unique_ptr<MultiRotor>(new MultiRotor(vehicle_params_, vehicle_api_,
getPose()));
@ -32,6 +34,19 @@ MultirotorSimApi::MultirotorSimApi(msr::airlib::MultirotorApiBase* vehicle_api,
did_reset_ = false;
}
void MultirotorSimApi::createVehicleApi()
{
//create vehicle params
std::shared_ptr<UnrealSensorFactory> sensor_factory = std::make_shared<UnrealSensorFactory>(getPawn(), &getNedTransform());
vehicle_params_ = MultiRotorParamsFactory::createConfig(getVehicleSetting(), sensor_factory);
vehicle_api_ = vehicle_params_->createMultirotorApi();
}
const msr::airlib::Kinematics::State* MultirotorSimApi::getGroundTruthKinematics() const
{
return & phys_vehicle_->getKinematics();
}
void MultirotorSimApi::updateRenderedState(float dt)
{
//Utils::log("------Render tick-------");

Просмотреть файл

@ -8,8 +8,6 @@
#include "common/Common.hpp"
#include "common/CommonStructs.hpp"
#include "ManualPoseController.h"
#include <chrono>
#include <future>
class MultirotorSimApi : public VehicleSimApi
@ -28,10 +26,9 @@ public:
//VehicleSimApiBase interface
//implements game interface to update pawn
MultirotorSimApi(msr::airlib::MultirotorApiBase* vehicle_api, msr::airlib::MultiRotorParams* vehicle_params,
UManualPoseController* manual_pose_controller,
APawn* pawn, const std::map<std::string, APIPCamera*>* cameras, const NedTransform& global_transform,
const std::string& vehicle_name);
MultirotorSimApi(APawn* pawn, const NedTransform& global_transform, CollisionSignal& collision_signal,
const std::map<std::string, APIPCamera*>& cameras,
UManualPoseController* manual_pose_controller);
virtual void updateRenderedState(float dt) override;
virtual void updateRendering(float dt) override;
@ -43,10 +40,19 @@ public:
virtual UpdatableObject* getPhysicsBody() override;
virtual void setPose(const Pose& pose, bool ignore_collision) override;
virtual const msr::airlib::Kinematics::State* getGroundTruthKinematics() const override;
msr::airlib::MultirotorApiBase* getVehicleApi()
{
return vehicle_api_.get();
}
private:
msr::airlib::MultirotorApiBase* vehicle_api_;
msr::airlib::MultiRotorParams* vehicle_params_;
void createVehicleApi();
private:
std::unique_ptr<msr::airlib::MultirotorApiBase> vehicle_api_;
std::unique_ptr<msr::airlib::MultiRotorParams> vehicle_params_;
UManualPoseController* manual_pose_controller_;
std::unique_ptr<MultiRotor> phys_vehicle_;

Просмотреть файл

@ -6,11 +6,11 @@
#include "AirBlueprintLib.h"
#include "vehicles/multirotor/api/MultirotorApiBase.hpp"
#include "MultirotorSimApi.h"
#include "physics/PhysicsBody.hpp"
#include "common/ClockFactory.hpp"
#include <memory>
#include "vehicles/multirotor/MultiRotorParamsFactory.hpp"
#include "UnrealSensors/UnrealSensorFactory.h"
#ifndef AIRLIB_NO_RPC
@ -38,16 +38,11 @@ ASimModeWorldMultiRotor::ASimModeWorldMultiRotor()
void ASimModeWorldMultiRotor::BeginPlay()
{
Super::BeginPlay();
}
std::unique_ptr<msr::airlib::ApiServerBase> ASimModeWorldMultiRotor::createApiServer() const
{
#ifdef AIRLIB_NO_RPC
return ASimModeBase::createApiServer();
#else
return std::unique_ptr<msr::airlib::ApiServerBase>(new msr::airlib::MultirotorRpcLibServer(
getApiProvider(), getSettings().api_server_address));
#endif
setupVehiclesAndCamera();
//let base class setup physics world
initializeForPlay();
}
void ASimModeWorldMultiRotor::EndPlay(const EEndPlayReason::Type EndPlayReason)
@ -55,26 +50,21 @@ void ASimModeWorldMultiRotor::EndPlay(const EEndPlayReason::Type EndPlayReason)
//stop physics thread before we dismantle
stopAsyncUpdator();
//for (AActor* actor : spawned_actors_) {
// actor->Destroy();
//}
spawned_actors_.Empty();
//fpv_vehicle_connectors_.Empty();
CameraDirector = nullptr;
external_camera_class_ = nullptr;
camera_director_class_ = nullptr;
vehicle_sim_apis_.clear();
spawned_actors_.RemoveAll();
Super::EndPlay(EndPlayReason);
}
VehicleSimApi* ASimModeWorldMultiRotor::getFpvVehicleSimApi() const
void ASimModeWorldMultiRotor::setupVehiclesAndCamera()
{
return fpv_vehicle_sim_api_;
}
void ASimModeWorldMultiRotor::setupVehiclesAndCamera(std::vector<VehiclePtr>& vehicles)
{
//put camera little bit above vehicle
//TODO: allow setting camera pose from settings
//get UU origin of global NED frame
FVector uu_origin = getGlobalNedTransform().getLocalOffset();
//TODO:make this configurable
FTransform camera_transform(uu_origin + FVector(-300, 0, 200));
//we will either find external camera if it already exist in environment or create one
@ -111,9 +101,12 @@ void ASimModeWorldMultiRotor::setupVehiclesAndCamera(std::vector<VehiclePtr>& ve
TArray<AActor*> pawns;
UAirBlueprintLib::FindAllActor<TMultiRotorPawn>(this, pawns);
TMultiRotorPawn* fpv_pawn = nullptr;
//add vehicles from settings
for (auto const& vehicle_setting_pair : getSettings().vehicles)
{
//if vehicle is of multirotor type and auto creatable
const auto& vehicle_setting = *vehicle_setting_pair.second;
if (vehicle_setting.auto_create &&
((vehicle_setting.vehicle_type == AirSimSettings::kVehicleTypeSimpleFlight) ||
@ -124,15 +117,7 @@ void ASimModeWorldMultiRotor::setupVehiclesAndCamera(std::vector<VehiclePtr>& ve
if (pawn_path == "")
pawn_path = "DefaultQuadrotor";
//create vehicle pawn
FActorSpawnParameters pawn_spawn_params;
pawn_spawn_params.Name = FName(vehicle_setting.vehicle_name.c_str());
pawn_spawn_params.SpawnCollisionHandlingOverride =
ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
auto vehicle_bp_class = UAirBlueprintLib::LoadClass(
getSettings().pawn_paths.at("DefaultQuadrotor").pawn_bp);
//compute initial pose
FVector spawn_position = uu_origin;
FRotator spawn_rotation = FRotator::ZeroRotator;
Vector3r settings_position = vehicle_setting.position;
@ -145,51 +130,76 @@ void ASimModeWorldMultiRotor::setupVehiclesAndCamera(std::vector<VehiclePtr>& ve
spawn_rotation.Pitch = rotation.pitch;
if (!std::isnan(rotation.roll))
spawn_rotation.Roll = rotation.roll;
//spawn vehicle pawn
FActorSpawnParameters pawn_spawn_params;
pawn_spawn_params.Name = FName(vehicle_setting.vehicle_name.c_str());
pawn_spawn_params.SpawnCollisionHandlingOverride =
ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
auto vehicle_bp_class = UAirBlueprintLib::LoadClass(
getSettings().pawn_paths.at("DefaultQuadrotor").pawn_bp);
TMultiRotorPawn* spawned_pawn = this->GetWorld()->SpawnActor<TMultiRotorPawn>(
vehicle_bp_class, FTransform(spawn_rotation, spawn_position), pawn_spawn_params);
spawned_actors_.Add(spawned_pawn);
pawns.Add(spawned_pawn);
if (vehicle_setting.is_fpv_vehicle)
fpv_pawn = spawned_pawn;
}
}
//set up vehicle pawns
fpv_vehicle_sim_api_ = nullptr;
//create API objects for each pawn we have
for (AActor* pawn : pawns)
{
//initialize each vehicle pawn we found
//initialize the pawn
TMultiRotorPawn* vehicle_pawn = static_cast<TMultiRotorPawn*>(pawn);
vehicle_pawn->initializeForBeginPlay(getGlobalNedTransform(), std::string(TCHAR_TO_UTF8(*this->GetName())));
const auto* vehicle_sim_api = vehicle_pawn->getVehicleSimApi();
//chose first pawn as FPV if none is designated as FPV
if (vehicle_sim_api->getVehicleSetting().is_fpv_vehicle || fpv_vehicle_sim_api_ == nullptr)
fpv_vehicle_sim_api_ = vehicle_sim_api;
vehicle_pawn->initializeForBeginPlay();
//now create the connector for each pawn
VehiclePtr vehicle = createVehicle(vehicle_sim_api);
if (vehicle != nullptr) {
vehicles.push_back(vehicle);
fpv_vehicle_connectors_.Add(vehicle);
}
//else we don't have vehicle for this pawn
//create vehicle sim api
auto vehicle_sim_api = std::unique_ptr<MultirotorSimApi>(new MultirotorSimApi(
vehicle_pawn, getGlobalNedTransform(),
vehicle_pawn->getCollisionSignal(), vehicle_pawn->getCameras(),
manual_pose_controller));
std::string vehicle_name = vehicle_sim_api->getVehicleName();
getApiProvider()->insert_or_assign(vehicle_name, vehicle_sim_api->getVehicleApi(),
vehicle_sim_api.get());
if ((fpv_pawn == vehicle_pawn || !getApiProvider()->hasDefaultVehicle()) && vehicle_name != "")
getApiProvider()->makeDefaultVehicle(vehicle_name);
vehicle_sim_apis_.push_back(std::move(vehicle_sim_api));
}
}
fpv_vehicle_sim_api_->possess();
CameraDirector->initializeForBeginPlay(getInitialViewMode(), fpv_vehicle_sim_api_, external_camera);
if (getApiProvider()->hasDefaultVehicle()) {
//TODO: better handle no FPV vehicles scenario
getVehicleSimApi()->possess();
CameraDirector->initializeForBeginPlay(getInitialViewMode(), getVehicleSimApi(), external_camera);
}
}
void ASimModeWorldMultiRotor::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
getFpvVehicleSimApi()->setLogLine(getLogString());
getVehicleSimApi()->setLogLine(getLogString());
}
std::unique_ptr<msr::airlib::ApiServerBase> ASimModeWorldMultiRotor::createApiServer() const
{
#ifdef AIRLIB_NO_RPC
return ASimModeBase::createApiServer();
#else
return std::unique_ptr<msr::airlib::ApiServerBase>(new msr::airlib::MultirotorRpcLibServer(
getApiProvider(), getSettings().api_server_address));
#endif
}
std::string ASimModeWorldMultiRotor::getLogString() const
{
const msr::airlib::Kinematics::State* kinematics = getFpvVehicleSimApi()->getGroundTruthKinematics();
const msr::airlib::Kinematics::State* kinematics = getVehicleSimApi()->getGroundTruthKinematics();
uint64_t timestamp_millis = static_cast<uint64_t>(msr::airlib::ClockFactory::get()->nowNanos() / 1.0E6);
//TODO: because this bug we are using alternative code with stringstream
@ -215,31 +225,10 @@ std::string ASimModeWorldMultiRotor::getLogString() const
//return ss.str();
}
void ASimModeWorldMultiRotor::createVehicles(std::vector<VehiclePtr>& vehicles)
{
//find vehicles and cameras available in environment
//if none available then we will create one
setupVehiclesAndCamera(vehicles);
}
ASimModeWorldBase::VehiclePtr ASimModeWorldMultiRotor::createVehicle(VehicleSimApi* vehicle_sim_api)
{
std::shared_ptr<UnrealSensorFactory> sensor_factory = std::make_shared<UnrealSensorFactory>(vehicle_sim_api->getPawn(), &vehicle_sim_api->getNedTransform());
auto vehicle_params = MultiRotorParamsFactory::createConfig(vehicle_sim_api->getVehicleSetting(), sensor_factory);
vehicle_params_.push_back(std::move(vehicle_params));
std::shared_ptr<MultirotorSimApi> vehicle = std::make_shared<MultirotorSimApi>(
vehicle_sim_api, vehicle_params_.back().get(), manual_pose_controller);
if (vehicle->getPhysicsBody() != nullptr)
vehicle_sim_api->setKinematics(&(static_cast<PhysicsBody*>(vehicle->getPhysicsBody())->getKinematics()));
return std::static_pointer_cast<VehicleSimApiBase>(vehicle);
}
void ASimModeWorldMultiRotor::setupClockSpeed()
{
typedef msr::airlib::ClockFactory ClockFactory;
float clock_speed = getSettings().clock_speed;
//setup clock in ClockFactory

Просмотреть файл

@ -4,10 +4,7 @@
#include "FlyingPawn.h"
#include "common/Common.hpp"
#include "MultirotorSimApi.h"
#include "vehicles/multirotor/MultiRotorParams.hpp"
#include "SimMode/SimModeWorldBase.h"
#include "VehicleSimApi.h"
#include "SimModeWorldMultiRotor.generated.h"
@ -22,32 +19,26 @@ public:
virtual void Tick( float DeltaSeconds ) override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
VehicleSimApi* getFpvVehicleSimApi() const override;
std::string getLogString() const;
protected:
typedef AFlyingPawn TMultiRotorPawn;
virtual void createVehicles(std::vector<VehiclePtr>& vehicles) override;
VehiclePtr createVehicle(VehicleSimApi* vehicle_sim_api);
virtual void setupClockSpeed() override;
virtual std::unique_ptr<msr::airlib::ApiServerBase> createApiServer() const override;
private:
void setupVehiclesAndCamera(std::vector<VehiclePtr>& vehicles);
void setupVehiclesAndCamera();
private:
typedef msr::airlib::ClockFactory ClockFactory;
TArray<uint8> image_;
std::vector <std::unique_ptr<msr::airlib::MultiRotorParams> > vehicle_params_;
//assets loaded in constructor
UClass* external_camera_class_;
UClass* camera_director_class_;
TArray<AActor*> spawned_actors_;
std::vector<std::unique_ptr<VehicleSimApiBase>>& vehicle_sim_apis_;
VehicleSimApi* fpv_vehicle_pawn_wrapper_;
TArray <std::shared_ptr<VehicleSimApiBase> > fpv_vehicle_connectors_;
UPROPERTY()
TArray<AActor*> spawned_actors_; //keep refs alive from Unreal GC
};

Просмотреть файл

@ -86,7 +86,7 @@ void ASimHUD::inputEventToggleHelp()
void ASimHUD::inputEventToggleTrace()
{
simmode_->getFpvVehicleSimApi()->toggleTrace();
simmode_->getVehicleSimApi()->toggleTrace();
}
ASimHUD::ImageType ASimHUD::getSubwindowCameraType(int window_index)
@ -291,7 +291,7 @@ void ASimHUD::createSimMode()
void ASimHUD::initializeSubWindows()
{
auto vehicle_sim_api = simmode_->getFpvVehicleSimApi();
auto vehicle_sim_api = simmode_->getVehicleSimApi();
auto camera_count = vehicle_sim_api->getCameraCount();
//setup defaults

Просмотреть файл

@ -92,6 +92,8 @@ void ASimModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
FRecordingThread::stopRecording();
world_sim_api_.reset(nullptr);
CameraDirector = nullptr;
Super::EndPlay(EndPlayReason);
}
@ -259,13 +261,6 @@ void ASimModeBase::reset()
//Should be overridden by derived classes
}
msr::airlib::VehicleSimApiBase* ASimModeBase::getFpvVehicleSimApi()
{
//Should be overridden by derived classes
return nullptr;
}
std::string ASimModeBase::getDebugReport()
{
static const std::string empty_string = std::string();
@ -307,9 +302,9 @@ void ASimModeBase::stopRecording()
void ASimModeBase::startRecording()
{
FRecordingThread::startRecording(getFpvVehicleSimApi()->getImageCapture(),
getFpvVehicleSimApi()->getGroundTruthKinematics(), getSettings().segmentation_setting,
getFpvVehicleSimApi());
FRecordingThread::startRecording(getVehicleSimApi()->getImageCapture(),
getVehicleSimApi()->getGroundTruthKinematics(), getSettings().recording_setting ,
getVehicleSimApi());
}
bool ASimModeBase::isRecording() const
@ -325,7 +320,7 @@ void ASimModeBase::startApiServer()
#ifdef AIRLIB_NO_RPC
api_server_.reset();
#else
api_provider_.reset(new msr::airlib::ApiProvider(world_sim_api_.get()));
api_provider_.reset(new msr::airlib::ApiProvider<VehicleSimApi>(world_sim_api_.get()));
api_server_ = createApiServer();
#endif

Просмотреть файл

@ -11,7 +11,7 @@
#include "common/ClockFactory.hpp"
#include "api/ApiServerBase.hpp"
#include "api/ApiProvider.hpp"
#include "api/VehicleSimApiBase.hpp"
#include "VehicleSimApi.h"
#include "SimModeBase.generated.h"
@ -41,8 +41,6 @@ public:
//additional overridable methods
virtual void reset();
virtual std::string getDebugReport();
msr::airlib::VehicleSimApiBase* ASimModeBase::getFpvVehicleSimApi();
virtual ECameraDirectorMode getInitialViewMode() const;
virtual bool isPaused() const;
@ -59,6 +57,20 @@ public:
const NedTransform& getGlobalNedTransform();
msr::airlib::ApiProvider* getApiProvider() const
{
return api_provider_.get();
}
const VehicleSimApi* getVehicleSimApi(const std::string& vehicle_name = "") const
{
return static_cast<VehicleSimApi*>(api_provider_->getVehicleSimApi(vehicle_name));
}
VehicleSimApi* getVehicleSimApi(const std::string& vehicle_name = "")
{
return static_cast<VehicleSimApi*>(api_provider_->getVehicleSimApi(vehicle_name));
}
protected:
virtual void setupInputBindings();
virtual const msr::airlib::AirSimSettings& getSettings() const;
@ -67,10 +79,6 @@ protected:
virtual void setupClockSpeed();
virtual std::unique_ptr<msr::airlib::ApiServerBase> createApiServer() const;
msr::airlib::ApiProvider* getApiProvider() const
{
return api_provider_.get();
}
protected:
typedef msr::airlib::AirSimSettings AirSimSettings;

Просмотреть файл

@ -9,27 +9,25 @@ void ASimModeWorldBase::BeginPlay()
manual_pose_controller = NewObject<UManualPoseController>();
setupInputBindings();
}
//call virtual method in derived class
createVehicles(vehicles_);
void ASimModeWorldBase::initializeForPlay()
{
physics_world_.reset(new msr::airlib::PhysicsWorld(
createPhysicsEngine(), toUpdatableObjects(vehicles_),
getPhysicsLoopPeriod()));
if (getSettings().usage_scenario == kUsageScenarioComputerVision) {
manual_pose_controller->initializeForPlay();
manual_pose_controller->setActor(getFpvVehicleSimApi()->getPawn());
manual_pose_controller->setActor(getVehicleSimApi()->getPawn());
}
}
void ASimModeWorldBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
//remove everything that we created in BeginPlay
physics_world_.reset();
physics_engine_.reset();
vehicles_.clear();
manual_pose_controller = nullptr;
Super::EndPlay(EndPlayReason);
@ -98,11 +96,6 @@ void ASimModeWorldBase::continueForTime(double seconds)
}
size_t ASimModeWorldBase::getVehicleCount() const
{
return vehicles_.size();
}
void ASimModeWorldBase::Tick(float DeltaSeconds)
{
{ //keep this lock as short as possible
@ -111,15 +104,15 @@ void ASimModeWorldBase::Tick(float DeltaSeconds)
physics_world_->enableStateReport(EnableReport);
physics_world_->updateStateReport();
for (auto& vehicle : vehicles_)
vehicle->updateRenderedState(DeltaSeconds);
for (auto& pair : getApiProvider()->getVehicleSimApis())
pair.second->updateRenderedState(DeltaSeconds);
physics_world_->unlock();
}
//perfom any expensive rendering update outside of lock region
for (auto& vehicle : vehicles_)
vehicle->updateRendering(DeltaSeconds);
//perform any expensive rendering update outside of lock region
for (auto& pair : getApiProvider()->getVehicleSimApis())
pair.second->updateRendering(DeltaSeconds);
Super::Tick(DeltaSeconds);
}
@ -138,9 +131,4 @@ std::string ASimModeWorldBase::getDebugReport()
return physics_world_->getDebugReport();
}
void ASimModeWorldBase::createVehicles(std::vector<VehiclePtr>& vehicles)
{
//should be overridden by derived class
//Unreal doesn't allow pure abstract methods in actors
}

Просмотреть файл

@ -33,27 +33,26 @@ public:
virtual void continueForTime(double seconds) override;
protected:
typedef std::shared_ptr<msr::airlib::VehicleSimApiBase> VehiclePtr;
virtual void createVehicles(std::vector<VehiclePtr>& vehicles);
size_t getVehicleCount() const;
UPROPERTY() UManualPoseController* manual_pose_controller;
void startAsyncUpdator();
void stopAsyncUpdator();
//should be called by derived class once all api_provider_ is ready to use
void initializeForPlay();
private:
typedef msr::airlib::UpdatableObject UpdatableObject;
typedef msr::airlib::PhysicsEngineBase PhysicsEngineBase;
typedef msr::airlib::ClockFactory ClockFactory;
//create the physics engine as needed from settings
PhysicsEngineBase* createPhysicsEngine();
static std::vector<UpdatableObject*> toUpdatableObjects(const std::vector<VehiclePtr>& vehicles);
private:
std::unique_ptr<msr::airlib::PhysicsWorld> physics_world_;
std::unique_ptr<PhysicsEngineBase> physics_engine_;
std::vector<VehiclePtr> vehicles_;
};

Просмотреть файл

@ -1,22 +1,27 @@
#include "VehicleSimApi.h"
#include "Engine/World.h"
#include "Kismet/KismetSystemLibrary.h"
#include "Kismet/GameplayStatics.h"
#include "Particles/ParticleSystemComponent.h"
#include "ConstructorHelpers.h"
#include "AirBlueprintLib.h"
#include "common/ClockFactory.hpp"
#include "PIPCamera.h"
#include "NedTransform.h"
#include "common/EarthUtils.hpp"
VehicleSimApi::VehicleSimApi(APawn* pawn, const std::map<std::string, APIPCamera*>* cameras, const NedTransform& global_transform,
const std::string& vehicle_name)
: pawn_(pawn), cameras_(cameras), vehicle_name_(vehicle_name), ned_transform_(pawn, global_transform)
VehicleSimApi::VehicleSimApi(APawn* pawn, const NedTransform& global_transform, CollisionSignal& collision_signal,
const std::map<std::string, APIPCamera*>& cameras)
: pawn_(pawn), vehicle_name_(TCHAR_TO_UTF8(*pawn->GetName())), ned_transform_(pawn, global_transform)
{
static ConstructorHelpers::FObjectFinder<UParticleSystem> collision_display(TEXT("ParticleSystem'/AirSim/StarterContent/Particles/P_Explosion.P_Explosion'"));
if (!collision_display.Succeeded())
collision_display_template = collision_display.Object;
else
collision_display_template = nullptr;
static ConstructorHelpers::FClassFinder<APIPCamera> pip_camera_class(TEXT("Blueprint'/AirSim/Blueprints/BP_PIPCamera'"));
pip_camera_class_ = pip_camera_class.Succeeded() ? pip_camera_class.Class : nullptr;
image_capture_.reset(new UnrealImageCapture(cameras_));
@ -36,9 +41,9 @@ VehicleSimApi::VehicleSimApi(APawn* pawn, const std::map<std::string, APIPCamera
Vector3r nedWrtOrigin = ned_transform_.toGlobalNed(getUUPosition());
home_geo_point_ = msr::airlib::EarthUtils::nedToGeodetic(nedWrtOrigin, AirSimSettings::singleton().origin_geopoint);
initial_state_.tracing_enabled = getVehicleSetting().enable_trace;
initial_state_.collisions_enabled = getVehicleSetting().enable_collisions;
initial_state_.passthrough_enabled = getVehicleSetting().enable_collision_passthrough;
initial_state_.tracing_enabled = getVehicleSetting()->enable_trace;
initial_state_.collisions_enabled = getVehicleSetting()->enable_collisions;
initial_state_.passthrough_enabled = getVehicleSetting()->enable_collision_passthrough;
initial_state_.collision_info = CollisionInfo();
@ -48,6 +53,10 @@ VehicleSimApi::VehicleSimApi(APawn* pawn, const std::map<std::string, APIPCamera
//setup RC
if (getRemoteControlID() >= 0)
detectUsbRc();
setupCamerasFromSettings(cameras);
//add listener for pawn's collision event
collision_signal.connect(this, &VehicleSimApi::onCollision);
}
void VehicleSimApi::detectUsbRc()
@ -63,20 +72,54 @@ void VehicleSimApi::detectUsbRc()
std::to_string(joystick_state_.connection_error_code), LogDebugLevel::Informational);
}
void VehicleSimApi::setupCamerasFromSettings()
void VehicleSimApi::setupCamerasFromSettings(const std::map<std::string, APIPCamera*>& cameras)
{
//add cameras that already exists in pawn
cameras_.clear();
for (const auto& p : cameras)
cameras_[p.first] = p.second;
//create or replace cameras specified in settings
createCamerasFromSettings();
//setup individual cameras
typedef msr::airlib::AirSimSettings AirSimSettings;
const auto& vehicle_setting = AirSimSettings::singleton().getVehicleSetting(vehicle_name_);
const auto& camera_defaults = AirSimSettings::singleton().camera_defaults;
for (auto& pair : *cameras_) {
const auto& camera_setting = Utils::findOrDefault(vehicle_setting->cameras, pair.first, camera_defaults);
for (auto& pair : cameras_) {
const auto& camera_setting = Utils::findOrDefault(getVehicleSetting()->cameras, pair.first, camera_defaults);
APIPCamera* camera = pair.second;
camera->setupCameraFromSettings(camera_setting, getNedTransform());
}
}
void VehicleSimApi::createCamerasFromSettings()
{
//UStaticMeshComponent* bodyMesh = UAirBlueprintLib::GetActorComponent<UStaticMeshComponent>(this, TEXT("BodyMesh"));
USceneComponent* bodyMesh = pawn_->GetRootComponent();
FActorSpawnParameters camera_spawn_params;
camera_spawn_params.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
const auto& transform = getNedTransform();
//for each camera in settings
for (const auto& camera_setting_pair : getVehicleSetting()->cameras) {
const auto& setting = camera_setting_pair.second;
//get pose
FVector position = transform.fromLocalNed(
NedTransform::Vector3r(setting.position.x, setting.position.y, setting.position.z))
- transform.fromLocalNed(NedTransform::Vector3r(0.0, 0.0, 0.0));
FTransform camera_transform(FRotator(setting.rotation.pitch, setting.rotation.yaw, setting.rotation.roll),
position, FVector(1., 1., 1.));
//spawn and attach camera to pawn
APIPCamera* camera = pawn_->GetWorld()->SpawnActor<APIPCamera>(pip_camera_class_, camera_transform, camera_spawn_params);
camera->AttachToComponent(bodyMesh, FAttachmentTransformRules::KeepRelativeTransform);
//add on to our collection
cameras_[camera_setting_pair.first] = camera;
}
}
void VehicleSimApi::onCollision(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation,
FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit)
{
@ -208,7 +251,7 @@ void VehicleSimApi::setGroundTruthKinematics(const msr::airlib::Kinematics::Stat
int VehicleSimApi::getRemoteControlID() const
{
return getVehicleSetting().rc.remote_control_id;
return getVehicleSetting()->rc.remote_control_id;
}
const APIPCamera* VehicleSimApi::getCamera(const std::string& camera_name) const

Просмотреть файл

@ -7,6 +7,7 @@
#include <memory>
#include "UnrealImageCapture.h"
#include "common/Common.hpp"
#include "common/common_utils/Signal.hpp"
#include "common/CommonStructs.hpp"
#include "PIPCamera.h"
#include "physics/Kinematics.hpp"
@ -28,7 +29,8 @@ public: //types
typedef msr::airlib::Utils Utils;
typedef msr::airlib::AirSimSettings::VehicleSetting VehicleSetting;
typedef msr::airlib::ImageCaptureBase ImageCaptureBase;
typedef common_utils::Signal<class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation,
FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit> CollisionSignal;
public: //implementation of VehicleSimApiBase
virtual void reset() override;
@ -48,14 +50,12 @@ public: //implementation of VehicleSimApiBase
return vehicle_name_;
}
virtual std::string getLogLine() const override;
virtual void setLogLine(std::string line) override;
virtual void toggleTrace() override;
public: //Unreal specific methods
VehicleSimApi(APawn* pawn, const std::map<std::string, APIPCamera*>* cameras, const NedTransform& global_transform,
const std::string& vehicle_name);
//on collision, pawns should update this
void onCollision(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp,
bool bSelfMoved, FVector HitLocation, FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit);
VehicleSimApi(APawn* pawn, const NedTransform& global_transform, CollisionSignal& collision_signal,
const std::map<std::string, APIPCamera*>& cameras);
//returns one of the cameras attached to the pawn
const APIPCamera* getCamera(const std::string& camera_name) const;
@ -72,29 +72,29 @@ public: //Unreal specific methods
//parameters in NED frame
void setDebugPose(const Pose& debug_pose);
void setLogLine(std::string line);
FVector getUUPosition() const;
FRotator getUUOrientation() const;
const NedTransform& getNedTransform() const;
void possess();
void setupCamerasFromSettings();
void toggleTrace();
//allows setting ground truth from physics engine
void setGroundTruthKinematics(const msr::airlib::Kinematics::State* kinematics);
protected:
UPROPERTY(VisibleAnywhere)
UParticleSystem* collision_display_template;
//allows setting ground truth from physics engine
void setGroundTruthKinematics(const msr::airlib::Kinematics::State* kinematics);
private: //methods
bool canTeleportWhileMove() const;
void allowPassthroughToggleInput();
void detectUsbRc();
void setupCamerasFromSettings(const std::map<std::string, APIPCamera*>& cameras);
void createCamerasFromSettings();
//on collision, pawns should update this
void onCollision(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp,
bool bSelfMoved, FVector HitLocation, FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit);
//these methods are for future usage
void plot(std::istream& s, FColor color, const Vector3r& offset);
@ -103,8 +103,11 @@ private: //methods
private: //vars
typedef msr::airlib::AirSimSettings AirSimSettings;
UPROPERTY() UClass* pip_camera_class_;
APawn* pawn_;
const std::map<std::string, APIPCamera*>* cameras_;
//TODO: should below be TMap to keep refs alive?
std::map<std::string, APIPCamera*> cameras_;
std::string vehicle_name_;
NedTransform ned_transform_;

Просмотреть файл

@ -80,8 +80,8 @@
<ClCompile Include="unreal\plugins\airsim\source\car\SimModeCar.cpp" />
<ClCompile Include="unreal\plugins\airsim\source\ManualPoseController.cpp" />
<ClCompile Include="unreal\plugins\airsim\source\multirotor\FlyingPawn.cpp" />
<ClCompile Include="unreal\plugins\airsim\source\multirotor\MultiRotorConnector.cpp" />
<ClCompile Include="unreal\plugins\airsim\source\multirotor\SimModeWorldMultiRotor.cpp" />
<ClCompile Include="Unreal\Plugins\AirSim\Source\Multirotor\MultirotorSimApi.cpp" />
<ClCompile Include="Unreal\Plugins\AirSim\Source\Multirotor\SimModeWorldMultirotor.cpp" />
<ClCompile Include="unreal\plugins\airsim\source\NedTransform.cpp" />
<ClCompile Include="unreal\plugins\airsim\source\PIPCamera.cpp" />
<ClCompile Include="unreal\plugins\airsim\source\recording\RecordingFile.cpp" />
@ -93,9 +93,12 @@
<ClCompile Include="unreal\plugins\airsim\source\simjoystick\SimJoyStick.cpp" />
<ClCompile Include="unreal\plugins\airsim\source\simmode\SimModeBase.cpp" />
<ClCompile Include="unreal\plugins\airsim\source\simmode\SimModeWorldBase.cpp" />
<ClCompile Include="Unreal\Plugins\AirSim\Source\UnrealImageCapture.cpp" />
<ClCompile Include="Unreal\Plugins\AirSim\Source\UnrealSensors\UnrealDistanceSensor.cpp" />
<ClCompile Include="Unreal\Plugins\AirSim\Source\UnrealSensors\UnrealSensorFactory.cpp" />
<ClCompile Include="unreal\plugins\airsim\source\VehicleCameraConnector.cpp" />
<ClCompile Include="unreal\plugins\airsim\source\VehicleConnectorBase.cpp" />
<ClCompile Include="unreal\plugins\airsim\source\VehiclePawnWrapper.cpp" />
<ClCompile Include="Unreal\Plugins\AirSim\Source\VehicleSimApi.cpp" />
<ClCompile Include="Unreal\Plugins\AirSim\Source\WorldSimApi.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="unreal\plugins\airsim\source\AirBlueprintLib.h" />
@ -109,6 +112,7 @@
<ClInclude Include="unreal\plugins\airsim\source\ManualPoseController.h" />
<ClInclude Include="unreal\plugins\airsim\source\multirotor\FlyingPawn.h" />
<ClInclude Include="unreal\plugins\airsim\source\multirotor\MultiRotorConnector.h" />
<ClInclude Include="Unreal\Plugins\AirSim\Source\Multirotor\MultirotorSimApi.h" />
<ClInclude Include="unreal\plugins\airsim\source\multirotor\SimModeWorldMultiRotor.h" />
<ClInclude Include="unreal\plugins\airsim\source\NedTransform.h" />
<ClInclude Include="unreal\plugins\airsim\source\PIPCamera.h" />
@ -121,8 +125,17 @@
<ClInclude Include="unreal\plugins\airsim\source\simjoystick\SimJoyStick.h" />
<ClInclude Include="unreal\plugins\airsim\source\simmode\SimModeBase.h" />
<ClInclude Include="unreal\plugins\airsim\source\simmode\SimModeWorldBase.h" />
<ClInclude Include="Unreal\Plugins\AirSim\Source\UnrealImageCapture.h" />
<ClInclude Include="Unreal\Plugins\AirSim\Source\UnrealSensors\UnrealDistanceSensor.h" />
<ClInclude Include="Unreal\Plugins\AirSim\Source\UnrealSensors\UnrealSensorFactory.h" />
<ClInclude Include="unreal\plugins\airsim\source\VehicleCameraConnector.h" />
<ClInclude Include="unreal\plugins\airsim\source\VehiclePawnWrapper.h" />
<ClInclude Include="Unreal\Plugins\AirSim\Source\VehicleSimApi.h" />
<ClInclude Include="Unreal\Plugins\AirSim\Source\WorldSimApi.h" />
</ItemGroup>
<ItemGroup>
<None Include="Unreal\Plugins\AirSim\Source\AirSim.Build.4.15.cs" />
<None Include="Unreal\Plugins\AirSim\Source\AirSim.Build.cs" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

Просмотреть файл

@ -42,12 +42,6 @@
<ClCompile Include="unreal\plugins\airsim\source\VehicleCameraConnector.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="unreal\plugins\airsim\source\VehicleConnectorBase.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="unreal\plugins\airsim\source\VehiclePawnWrapper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="unreal\plugins\airsim\source\car\CarPawn.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -63,12 +57,6 @@
<ClCompile Include="unreal\plugins\airsim\source\multirotor\FlyingPawn.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="unreal\plugins\airsim\source\multirotor\MultiRotorConnector.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="unreal\plugins\airsim\source\multirotor\SimModeWorldMultiRotor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="unreal\plugins\airsim\source\recording\RecordingFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -93,6 +81,27 @@
<ClCompile Include="unreal\plugins\airsim\source\simmode\SimModeWorldBase.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Unreal\Plugins\AirSim\Source\UnrealImageCapture.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Unreal\Plugins\AirSim\Source\VehicleSimApi.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Unreal\Plugins\AirSim\Source\WorldSimApi.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Unreal\Plugins\AirSim\Source\UnrealSensors\UnrealDistanceSensor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Unreal\Plugins\AirSim\Source\UnrealSensors\UnrealSensorFactory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Unreal\Plugins\AirSim\Source\Multirotor\MultirotorSimApi.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Unreal\Plugins\AirSim\Source\Multirotor\SimModeWorldMultirotor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="unreal\plugins\airsim\source\AirBlueprintLib.h">
@ -170,5 +179,31 @@
<ClInclude Include="unreal\plugins\airsim\source\simmode\SimModeWorldBase.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Unreal\Plugins\AirSim\Source\UnrealImageCapture.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="Unreal\Plugins\AirSim\Source\VehicleSimApi.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="Unreal\Plugins\AirSim\Source\WorldSimApi.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="Unreal\Plugins\AirSim\Source\UnrealSensors\UnrealDistanceSensor.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="Unreal\Plugins\AirSim\Source\UnrealSensors\UnrealSensorFactory.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="Unreal\Plugins\AirSim\Source\Multirotor\MultirotorSimApi.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="Unreal\Plugins\AirSim\Source\AirSim.Build.4.15.cs">
<Filter>Source Files</Filter>
</None>
<None Include="Unreal\Plugins\AirSim\Source\AirSim.Build.cs">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>