Examples presented in this document and the plugin have been made in Unreal Engine 4.14, 4.15, 4.18 and 4.20+. They might not work correctly with different versions of the Unreal Engine.

Plugin integration

Please follow below steps in order to include ForceSeatMI plugin into your project.

  1. Create C++ Unreal Engine project
  2. Inside root directory of your project create Plugins directory
  3. Copy ForceSeatMI plugin folder into Plugins directory
  4. Launch Unreal Engine editor
  5. Add ForceSeatMI plugin dependency to your project inside YourProject.Build.cs
    PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ForceSeatMI" });
  6. UE 4.15+ users: ForceSeatMI_VehicleTelemetry requires PhysXVehicles so make sure that this module it is added to your project
  7. After everything is built and compiled you can start using ForceSeatMI in your application!
ForceSeatMI plugin uses DLL which is installed as part of the ForceSeatPM software. Make sure that you have ForceSeatPM installed on your computer.

Application: top table positioning

Examples:

  • TableLogPos_Unreal shows positioning in abstract(logical, percents) units
  • TablePhyPos_Unreal shows positioning in real world units (Inverse Kinematics)

For both examples, use built-in ForceSeatPM profile SDK – Positioning.

Positioning application requires usage of raw ForceSeatMI API. Typical operation routine consists of following steps:

  1. Create a pointer member variable inside your class which will point to an instance of IForceSeatMI_API:
    IForceSeatMI_API* m_api;
  2. Initialize it in class constructor:
    m_api(&IForceSeatMI::Get().GetAPI())
  3. When simulation starts call (e.g. in BeginPlay() method of your APawn implementation):
    m_api->BeginMotionControl();
  4. The SIM should send positioning data in constant intervals using one of the following functions:
    m_api->SendTopTablePosLog(...);
    m_api->SendTopTablePosPhy(...);
    m_api->SendTopTableMatrixPhy(...);
  5. At the end of simulation call:
    m_api->EndMotionControl();

Code

Below code comes from TableLogPos_Unreal example.

ATableLogPos_UnrealPawn::ATableLogPos_UnrealPawn()
  : CurrentDrawingHeave(0)
  , CurrentDrawingPitch(0)
  , CurrentDrawingRoll(0)
{
  // ... generated UE4 code removed for better clarity
 
  // ForceSeatMI - BEGIN
  memset(&PlatformPosition, 0, sizeof(PlatformPosition));
  PlatformPosition.structSize = sizeof(PlatformPosition);
 
  // The demo program is able to provide pause, position and speed limit
  PlatformPosition.maxSpeed = PLATFORM_MAX_SPEED;
  PlatformPosition.mask     = FSMI_POS_BIT_STATE | FSMI_POS_BIT_POSITION | FSMI_POS_BIT_MAX_SPEED;
  // ForceSeatMI - END
}
 
void ATableLogPos_UnrealPawn::Tick(float DeltaTime)
{
  Super::Tick(DeltaTime);
 
  // ... generated UE4 code removed for better clarity
 
  // ForceSeatMI - BEGIN
  SendCoordinatesToPlatform();
  // ForceSeatMI - END
}
 
void ATableLogPos_UnrealPawn::BeginPlay()
{
  Super::BeginPlay();
 
  // ForceSeatMI - BEGIN
  if (FSMI_True == IForceSeatMI::Get().GetAPI().BeginMotionControl())
  {
    SendCoordinatesToPlatform();
  }
  // ForceSeatMI - END
 
  // ... generated UE4 code removed for better clarity
}
 
void ATableLogPos_UnrealPawn::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
  Super::EndPlay(EndPlayReason);
 
  // ForceSeatMI - BEGIN
  IForceSeatMI::Get().GetAPI().EndMotionControl();
  // ForceSeatMI - END
}
 
void ATableLogPos_UnrealPawn::SendCoordinatesToPlatform()
{
  // ForceSeatMI - BEGIN
  PlatformPosition.state = FSMI_STATE_NO_PAUSE;
  PlatformPosition.roll = static_cast(FMath::Clamp(CurrentDrawingRoll / DRAWING_ROLL_MAX  * PLATFORM_POSITION_LOGIC_MAX, PLATFORM_POSITION_LOGIC_MIN, PLATFORM_POSITION_LOGIC_MAX));
  PlatformPosition.pitch = static_cast(FMath::Clamp(CurrentDrawingPitch / DRAWING_PITCH_MAX * PLATFORM_POSITION_LOGIC_MAX, PLATFORM_POSITION_LOGIC_MIN, PLATFORM_POSITION_LOGIC_MAX));
  PlatformPosition.heave = static_cast(FMath::Clamp(CurrentDrawingHeave / DRAWING_HEAVE_MAX * PLATFORM_POSITION_LOGIC_MAX, PLATFORM_POSITION_LOGIC_MIN, PLATFORM_POSITION_LOGIC_MAX));
 
  IForceSeatMI::Get().GetAPI().SendTopTablePosLog(&PlatformPosition);
  // ForceSeatMI - END
}

Application: vehicle simulation

Examples: Telemetry_Veh_Unreal (use built-in ForceSeatPM profile SDK – Vehicle Telemetry)

Vehicle simulation application requires PhysXVehicles and extracts automatically all necessary data from APawn and UWheeledVehicleMovementComponent objects.
Typical operation routine consists of following steps:

  1. Set application ID if you have one or leave it empty
    IForceSeatMI::Get().SetAppID("");
  2. Activate coresponding profile
    IForceSeatMI::Get().ActivateProfile("SDK - Vehicle Telemetry");
  3. Set telemetry object that represents your vehicle
    IForceSeatMI::Get().SetTelemetryObject(IForceSeatMI::Get().CreateVehicle(*this));
  4. Set simulation state and call Begin method
    IForceSeatMI::Get().Pause(false);
    IForceSeatMI::Get().Begin();
  5. The SIM should send telemetry data in constant intervals using following function:
    IForceSeatMI::Get().Update(Delta);

Code

Below code comes from Telemetry_Veh_Unreal example.

void ATelemetry_Veh_UnrealPawn::Tick(float Delta)
{
  Super::Tick(Delta);
 
  // ... generated UE4 code removed for better clarity
 
  ++Iterator;
  // ForceSeatMI - BEGIN
  // Use extra parameters to generate custom effects, for exmp. vibrations. They will NOT be
  // filtered, smoothed or processed in any way.
 
  Parameters.yaw = 0;
  Parameters.pitch = 0;
  Parameters.roll = sinf(Iterator) * 0.05f;
  Parameters.sway = 0;
  Parameters.heave = 0;
  Parameters.surge = 0;
 
  IForceSeatMI::Get().AddExtra(Parameters);
  IForceSeatMI::Get().Update(Delta);
  // ForceSeatMI - END
}
void ATelemetry_Veh_UnrealPawn::BeginPlay()
{
  Super::BeginPlay();
  Iterator = 0;
 
  // ForceSeatMI - BEGIN
  IForceSeatMI::Get().SetAppID(""); // If you have dedicated app id, remove ActivateProfile calls from your code
  IForceSeatMI::Get().ActivateProfile("SDK - VehicleTelemetry");
  IForceSeatMI::Get().SetTelemetryObject(IForceSeatMI::Get().CreateVehicle(*this));
  IForceSeatMI::Get().Pause(false);
  IForceSeatMI::Get().Begin();
  // ForceSeatMI - END
}

Application: flight simulation

Examples: Telemetry_Fly_Unreal (use built-in ForceSeatPM profile SDK – Plane Telemetry)

Typical operation routine consists of following steps:

  1. Set application ID if you have one or leave it empty
    IForceSeatMI::Get().SetAppID("");
  2. Activate coresponding profile
    IForceSeatMI::Get().ActivateProfile("SDK - Plane Telemetry");
  3. Set telemetry object that represents your plane
    IForceSeatMI::Get().SetTelemetryObject(IForceSeatMI::Get().CreateAeroplane(*this));
  4. Set simulation state and call Begin method
    IForceSeatMI::Get().Pause(false);
    IForceSeatMI::Get().Begin();
  5. The SIM should send telemetry data in constant intervals using following function:
    IForceSeatMI::Get().Update(DeltaSeconds);

Code

Below code comes from Telemetry_Fly_Unreal example.

void ATelemetry_Fly_UnrealPawn::Tick(float DeltaSeconds)
{
  // ... generated UE4 code removed for better clarity
 
  / Call any parent class Tick implementation
  Super::Tick(DeltaSeconds);
 
  // ForceSeatMI - BEGIN
  // Use extra parameters to generate custom effects, for exmp. vibrations. They will NOT be
  // filtered, smoothed or processed in any way.
  Parameters.yaw = 0;
  Parameters.pitch = 0;
  Parameters.roll = sinf(Iterator) * 0.05f;
  Parameters.sway = 0;
  Parameters.heave = 0;
  Parameters.surge = 0;
 
  IForceSeatMI::Get().AddExtra(Parameters);
  IForceSeatMI::Get().Update(DeltaSeconds);
  // ForceSeatMI - END
}
void ATelemetry_Fly_UnrealPawn::BeginPlay()
{
 Super::BeginPlay();
 
  Iterator = 0;
 
  // ForceSeatMI - BEGIN IForceSeatMI::Get().SetAppID(""); // If you have dedicated app id, remove ActivateProfile calls from your code
  IForceSeatMI::Get().ActivateProfile("SDK - Plane Telemetry");
  IForceSeatMI::Get().SetTelemetryObject(IForceSeatMI::Get().CreateAeroplane(*this));
  IForceSeatMI::Get().Pause(false);
  IForceSeatMI::Get().Begin();
  // ForceSeatMI - END
}

Powiązane artykuły

Poniższe artykuły mogą Cię zainteresować. Jeśli chcesz pobrać SDK, odwiedź stronę produktu.