Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions AirLib/update_mavlibkcom.bat
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
robocopy /MIR ..\MavLinkCom\SDK\Includes deps\MavLinkCom\include /XD temp *. /njh /njs /ndl /np
robocopy /MIR ..\MavLinkCom\SDK\Libraries deps\MavLinkCom\lib /XD temp *. /njh /njs /ndl /np
pause
@echo off
setlocal

set "MAVLINKCOM_ROOT=..\MavLinkCom"
set "INCLUDE_SRC=%MAVLINKCOM_ROOT%\SDK\Includes"
set "LIB_SRC=%MAVLINKCOM_ROOT%\SDK\Libraries"

if exist "%MAVLINKCOM_ROOT%\include" set "INCLUDE_SRC=%MAVLINKCOM_ROOT%\include"
if exist "%MAVLINKCOM_ROOT%\lib" set "LIB_SRC=%MAVLINKCOM_ROOT%\lib"

if not exist "%INCLUDE_SRC%" (
echo [update_mavlibkcom] Include source not found: %INCLUDE_SRC%
exit /b 1
)

if not exist "%LIB_SRC%" (
echo [update_mavlibkcom] Library source not found: %LIB_SRC%
exit /b 1
)

robocopy /MIR "%INCLUDE_SRC%" deps\MavLinkCom\include /XD temp *. /njh /njs /ndl /np
if %errorlevel% geq 8 exit /b %errorlevel%

robocopy /MIR "%LIB_SRC%" deps\MavLinkCom\lib /XD temp *. /njh /njs /ndl /np
if %errorlevel% geq 8 exit /b %errorlevel%

exit /b 0
10 changes: 10 additions & 0 deletions MavLinkCom/common_utils/Utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@
#include <limits.h> // needed for CHAR_BIT used below
#endif

#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif

//Stubs for C++17 optional type
#if (defined __cplusplus) && (__cplusplus >= 201700L)
#include <optional>
Expand Down Expand Up @@ -80,11 +87,14 @@ __attribute__((__format__(__printf__, 1, 0))) static int _vscprintf(const char*
#endif

// Call this on a function parameter to suppress the unused paramter warning
#ifndef AIRSIM_UNUSED_HELPER_DEFINED
#define AIRSIM_UNUSED_HELPER_DEFINED
template <class T>
inline void unused(T const& result)
{
static_cast<void>(result);
}
#endif

namespace mavlink_utils
{
Expand Down
4 changes: 4 additions & 0 deletions Unreal/Plugins/AirSim/AirSim.uplugin
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
}
],
"Plugins": [
{
"Name": "Carla",
"Enabled": true
},
{
"Name": "PhysXVehicles",
"Enabled": true
Expand Down
41 changes: 14 additions & 27 deletions Unreal/Plugins/AirSim/Source/AirBlueprintLib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "Components/StaticMeshComponent.h"
#include "EngineUtils.h"
#include "Runtime/Engine/Classes/Engine/StaticMesh.h"
#include "Runtime/Engine/Classes/Engine/LevelStreamingDynamic.h"
#include "UObject/UObjectIterator.h"
#include "Camera/CameraComponent.h"
#include "Runtime/Engine/Classes/GameFramework/PlayerStart.h"
Expand All @@ -20,6 +21,7 @@
#include "Misc/ObjectThumbnail.h"
#include "Engine/Engine.h"
#include "Engine/World.h"
#include <CineCameraComponent.h>
#include <exception>
#include "common/common_utils/Utils.hpp"
#include "Modules/ModuleManager.h"
Expand All @@ -34,6 +36,7 @@ Methods -> CamelCase
parameters -> camel_case
*/

ULevelStreamingDynamic* UAirBlueprintLib::CURRENT_LEVEL = nullptr;
bool UAirBlueprintLib::log_messages_hidden_ = false;
msr::airlib::AirSimSettings::SegmentationSetting::MeshNamingMethodType UAirBlueprintLib::mesh_naming_method_ =
msr::airlib::AirSimSettings::SegmentationSetting::MeshNamingMethodType::OwnerName;
Expand Down Expand Up @@ -74,23 +77,18 @@ void UAirBlueprintLib::setSimulatePhysics(AActor* actor, bool simulate_physics)
}
}

bool UAirBlueprintLib::loadLevel(UObject* context, const FString& level_name)
ULevelStreamingDynamic* UAirBlueprintLib::loadLevel(UObject* context, const FString& level_name)
{

bool success{ false };
// Get name of current level
auto currMap = context->GetWorld()->GetMapName();
currMap.RemoveFromStart(context->GetWorld()->StreamingLevelsPrefix);
// Only load new level if different from current level
if (!currMap.Equals(level_name)) {
FString LongPackageName;
success = FPackageName::SearchForPackageOnDisk(level_name, &LongPackageName);
if (success) {
context->GetWorld()->SetNewWorldOrigin(FIntVector(0, 0, 0));
UGameplayStatics::OpenLevel(context->GetWorld(), FName(*LongPackageName), true);
}
context->GetWorld()->SetNewWorldOrigin(FIntVector(0, 0, 0));
ULevelStreamingDynamic* new_level = UAirsimLevelStreaming::LoadAirsimLevelInstance(
context->GetWorld(), level_name, FVector(0, 0, 0), FRotator(0, 0, 0), success);
if (success) {
if (CURRENT_LEVEL != nullptr && CURRENT_LEVEL->IsValidLowLevel())
CURRENT_LEVEL->SetShouldBeLoaded(false);
CURRENT_LEVEL = new_level;
}
return success;
return CURRENT_LEVEL;
}

bool UAirBlueprintLib::spawnPlayer(UWorld* context)
Expand Down Expand Up @@ -316,6 +314,7 @@ template USceneCaptureComponent2D* UAirBlueprintLib::GetActorComponent(AActor*,
template UStaticMeshComponent* UAirBlueprintLib::GetActorComponent(AActor*, FString);
template URotatingMovementComponent* UAirBlueprintLib::GetActorComponent(AActor*, FString);
template UCameraComponent* UAirBlueprintLib::GetActorComponent(AActor*, FString);
template UCineCameraComponent* UAirBlueprintLib::GetActorComponent(AActor*, FString);
template UDetectionComponent* UAirBlueprintLib::GetActorComponent(AActor*, FString);

bool UAirBlueprintLib::IsInGameThread()
Expand Down Expand Up @@ -458,12 +457,8 @@ std::vector<msr::airlib::MeshPositionVertexBuffersResponse> UAirBlueprintLib::Ge

//Various checks if there is even a valid mesh
if (!comp->GetStaticMesh()) continue;
if (!comp->GetStaticMesh()->HasValidRenderData()) continue;
#if ((ENGINE_MAJOR_VERSION > 4) || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 27))
if (comp->GetStaticMesh()->GetRenderData()->LODResources.Num() == 0) continue;
#else
if (!comp->GetStaticMesh()->RenderData) continue;
if (comp->GetStaticMesh()->RenderData->LODResources.Num() == 0) continue;
#endif

msr::airlib::MeshPositionVertexBuffersResponse mesh;
mesh.name = name;
Expand All @@ -478,11 +473,7 @@ std::vector<msr::airlib::MeshPositionVertexBuffersResponse> UAirBlueprintLib::Ge
mesh.orientation.y() = att.Y;
mesh.orientation.z() = att.Z;

#if ((ENGINE_MAJOR_VERSION > 4) || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 27))
FPositionVertexBuffer* vertex_buffer = &comp->GetStaticMesh()->GetRenderData()->LODResources[0].VertexBuffers.PositionVertexBuffer;
#else
FPositionVertexBuffer* vertex_buffer = &comp->GetStaticMesh()->RenderData->LODResources[0].VertexBuffers.PositionVertexBuffer;
#endif
if (vertex_buffer) {
const int32 vertex_count = vertex_buffer->VertexBufferRHI->GetSize();
TArray<FVector> vertices;
Expand All @@ -497,11 +488,7 @@ std::vector<msr::airlib::MeshPositionVertexBuffersResponse> UAirBlueprintLib::Ge
RHIUnlockVertexBuffer(vertex_buffer->VertexBufferRHI);
});

#if ((ENGINE_MAJOR_VERSION > 4) || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 27))
FStaticMeshLODResources& lod = comp->GetStaticMesh()->GetRenderData()->LODResources[0];
#else
FStaticMeshLODResources& lod = comp->GetStaticMesh()->RenderData->LODResources[0];
#endif
FRawStaticIndexBuffer* IndexBuffer = &lod.IndexBuffer;
int num_indices = IndexBuffer->IndexBufferRHI->GetSize() / IndexBuffer->IndexBufferRHI->GetStride();

Expand Down
7 changes: 6 additions & 1 deletion Unreal/Plugins/AirSim/Source/AirBlueprintLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@
#include "Engine/World.h"
#include "Runtime/Landscape/Classes/LandscapeComponent.h"
#include "Runtime/Engine/Classes/Kismet/GameplayStatics.h"
#include "AirsimLevelStreaming.h"
#include "Runtime/Core/Public/HAL/FileManager.h"
#include "common/AirSimSettings.hpp"
#include <string>
#include <regex>
#include "AirBlueprintLib.generated.h"

class ULevelStreamingDynamic;

UENUM(BlueprintType)
enum class LogDebugLevel : uint8
{
Expand Down Expand Up @@ -71,9 +74,11 @@ class UAirBlueprintLib : public UBlueprintFunctionLibrary
UGameplayStatics::GetAllActorsOfClass(context, T::StaticClass(), foundActors);
}

static ULevelStreamingDynamic* CURRENT_LEVEL;

static std::vector<std::string> ListMatchingActors(const UObject* context, const std::string& name_regex);
UFUNCTION(BlueprintCallable, Category = "AirSim|LevelAPI")
static bool loadLevel(UObject* context, const FString& level_name);
static ULevelStreamingDynamic* loadLevel(UObject* context, const FString& level_name);
UFUNCTION(BlueprintCallable, Category = "AirSim|LevelAPI")
static bool spawnPlayer(UWorld* context);
UFUNCTION(BlueprintPure, Category = "AirSim|LevelAPI")
Expand Down
4 changes: 3 additions & 1 deletion Unreal/Plugins/AirSim/Source/AirSim.Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,17 @@ public AirSim(ReadOnlyTargetRules Target) : base(Target)
bEnableExceptions = true;

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ImageWrapper", "RenderCore", "RHI", "AssetRegistry", "PhysicsCore", "PhysXVehicles", "PhysXVehicleLib", "PhysX", "APEX", "Landscape", "CinematicCamera" });
PrivateDependencyModuleNames.AddRange(new string[] { "UMG", "Slate", "SlateCore" });
PrivateDependencyModuleNames.AddRange(new string[] { "UMG", "Slate", "SlateCore", "Carla", "Foliage" });

//suppress VC++ proprietary warnings
PublicDefinitions.Add("_SCL_SECURE_NO_WARNINGS=1");
PublicDefinitions.Add("_CRT_SECURE_NO_WARNINGS=1");
PublicDefinitions.Add("HMD_MODULE_INCLUDED=0");
PublicDefinitions.Add("NOMINMAX");

PublicIncludePaths.Add(Path.Combine(AirLibPath, "include"));
PublicIncludePaths.Add(Path.Combine(AirLibPath, "deps", "eigen3"));
PublicIncludePaths.Add(Path.Combine(ModulePath, "MavLinkCom", "common_utils"));
AddOSLibDependencies(Target);

SetupCompileMode(CompileMode.HeaderOnlyWithRpc, Target);
Expand Down
21 changes: 20 additions & 1 deletion Unreal/Plugins/AirSim/Source/AirSim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
#include "Misc/Paths.h"
#include "Modules/ModuleManager.h"
#include "Modules/ModuleInterface.h"
#if WITH_EDITOR
#include <compiler/disable-ue4-macros.h>
#include <carla/Exception.h>
#include <compiler/enable-ue4-macros.h>
#include <exception>
#endif

class FAirSim : public IModuleInterface
{
Expand All @@ -23,4 +29,17 @@ void FAirSim::StartupModule()
void FAirSim::ShutdownModule()
{
//plugin shutdown
}
}

#if WITH_EDITOR
namespace carla
{

void throw_exception(const std::exception& e)
{
UE_LOG(LogTemp, Fatal, TEXT("Carla exception forwarded via AirSim: %s"), UTF8_TO_TCHAR(e.what()));
std::terminate();
}

} // namespace carla
#endif
48 changes: 48 additions & 0 deletions Unreal/Plugins/AirSim/Source/AirsimLevelStreaming.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#pragma once

#include "AirsimLevelStreaming.h"
#include "Engine/World.h"

int32 UAirsimLevelStreaming::LevelInstanceId = 0;

UAirsimLevelStreaming* UAirsimLevelStreaming::LoadAirsimLevelInstance(UWorld* WorldContextObject, FString LevelName, FVector Location, FRotator Rotation, bool& bOutSuccess)
{
if (!WorldContextObject) {
return nullptr;
}

// Check whether requested map exists, this could be very slow if LevelName is a short package name
FString LongPackageName;
bool success = FPackageName::SearchForPackageOnDisk(LevelName, &LongPackageName);
if (!success) {
bOutSuccess = false;
return nullptr;
}

// Create Unique Name for sub-level package
const FString ShortPackageName = FPackageName::GetShortName(LongPackageName);
const FString PackagePath = FPackageName::GetLongPackagePath(LongPackageName);
FString UniqueLevelPackageName = PackagePath + TEXT("/") + WorldContextObject->StreamingLevelsPrefix + ShortPackageName;
UniqueLevelPackageName += TEXT("_LevelInstance_") + FString::FromInt(++LevelInstanceId);

// Setup streaming level object that will load specified map
ULevelStreamingDynamic* level_pointer = NewObject<ULevelStreamingDynamic>(WorldContextObject, ULevelStreamingDynamic::StaticClass(), NAME_None, RF_Transient, NULL);
level_pointer->SetWorldAssetByPackageName(FName(*UniqueLevelPackageName));
level_pointer->LevelColor = FColor::MakeRandomColor();
level_pointer->SetShouldBeLoaded(true);
level_pointer->SetShouldBeVisible(true);
level_pointer->bShouldBlockOnLoad = true;
level_pointer->bInitiallyLoaded = true;
level_pointer->bInitiallyVisible = true;

// Transform
level_pointer->LevelTransform = FTransform(Rotation, Location);
// Map to Load
level_pointer->PackageNameToLoad = FName(*LongPackageName);
// Add the new level to world.
WorldContextObject->AddStreamingLevel(level_pointer);

bOutSuccess = true;

return dynamic_cast<UAirsimLevelStreaming*>(level_pointer);
}
11 changes: 11 additions & 0 deletions Unreal/Plugins/AirSim/Source/AirsimLevelStreaming.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once
#include "Runtime/Engine/Classes/Engine/LevelStreamingDynamic.h"

class UAirsimLevelStreaming : public ULevelStreamingDynamic
{
public:
static UAirsimLevelStreaming* LoadAirsimLevelInstance(UWorld* WorldContextObject, FString LevelName, FVector Location, FRotator Rotation, bool& bOutSuccess);

private:
static int32 LevelInstanceId;
};
35 changes: 32 additions & 3 deletions Unreal/Plugins/AirSim/Source/CameraDirector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ void ACameraDirector::Tick(float DeltaTime)
Super::Tick(DeltaTime);

if (mode_ == ECameraDirectorMode::CAMERA_DIRECTOR_MODE_MANUAL) {
manual_pose_controller_->updateActorPose(DeltaTime);
if (manual_pose_controller_)
manual_pose_controller_->updateActorPose(DeltaTime);
}
else if (mode_ == ECameraDirectorMode::CAMERA_DIRECTOR_MODE_SPRINGARM_CHASE) {
//do nothing, spring arm is pulling the camera with it
Expand All @@ -56,6 +57,7 @@ void ACameraDirector::initializeForBeginPlay(ECameraDirectorMode view_mode,
setupInputBindings();

mode_ = view_mode;
mode_before_front_ = view_mode; // default restore target = initial view

follow_actor_ = follow_actor;
fpv_camera_ = fpv_camera;
Expand Down Expand Up @@ -151,7 +153,7 @@ void ACameraDirector::setMode(ECameraDirectorMode mode)

//Remove any existing key bindings for manual mode
if (mode != ECameraDirectorMode::CAMERA_DIRECTOR_MODE_MANUAL) {
if (ExternalCamera != nullptr && manual_pose_controller_->getActor() == ExternalCamera) {
if (ExternalCamera != nullptr && manual_pose_controller_ && manual_pose_controller_->getActor() == ExternalCamera) {

manual_pose_controller_->setActor(nullptr);
}
Expand Down Expand Up @@ -286,13 +288,40 @@ void ACameraDirector::inputEventBackupView()

void ACameraDirector::inputEventFrontView()
{
// Toggle: if already in Front view → restore the view that was active before pressing I
if (mode_ == ECameraDirectorMode::CAMERA_DIRECTOR_MODE_FRONT || mode_ == ECameraDirectorMode::CAMERA_DIRECTOR_MODE_FPV) {
// Restore previous mode
switch (mode_before_front_) {
case ECameraDirectorMode::CAMERA_DIRECTOR_MODE_GROUND_OBSERVER:
inputEventGroundView();
break;
case ECameraDirectorMode::CAMERA_DIRECTOR_MODE_MANUAL:
inputEventManualView();
break;
case ECameraDirectorMode::CAMERA_DIRECTOR_MODE_SPRINGARM_CHASE:
inputEventSpringArmChaseView();
break;
case ECameraDirectorMode::CAMERA_DIRECTOR_MODE_BACKUP:
inputEventBackupView();
break;
default:
// FLY_WITH_ME or anything else
inputEventFlyWithView();
break;
}
return;
}

// Save current mode before switching to front view
mode_before_front_ = mode_;

if (front_camera_) {
setMode(ECameraDirectorMode::CAMERA_DIRECTOR_MODE_FRONT);
front_camera_->showToScreen();
disableCameras(true, true, true, false);
}
else
UAirBlueprintLib::LogMessageString("Camera is not available: ", "backup_camera", LogDebugLevel::Failure);
UAirBlueprintLib::LogMessageString("Camera is not available: ", "front_camera", LogDebugLevel::Failure);

notifyViewModeChanged();
}
Expand Down
1 change: 1 addition & 0 deletions Unreal/Plugins/AirSim/Source/CameraDirector.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class AIRSIM_API ACameraDirector : public AActor
USceneComponent* last_parent_ = nullptr;

ECameraDirectorMode mode_;
ECameraDirectorMode mode_before_front_; // saved mode before I-key toggle
UPROPERTY()
UManualPoseController* manual_pose_controller_;

Expand Down
Loading
Loading