Skip to main content

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

  1. Create Unity 3D project
  2. Inside Assets directory of your project create ForceSeatMI directory
  3. Copy following files into ForceSeatMI directory (for the reference you can check any of our Unity 3D examples)
    • ForceSeatMI.cs
    • ForceSeatMI_Common.cs
    • ForceSeatMI_ITelemetryInterface.cs
    • ForceSeatMI_Positioning.cs
    • ForceSeatMI_Status.cs
    • ForceSeatMI_TactileTranscuders.cs
    • ForceSeatMI_Telemetry.cs
    • ForceSeatMI_TelemetryACE.cs
    • ForceSeatMI_Unity.cs
    • ForceSeatMI_Aeroplane.cs
    • ForceSeatMI_Vehicle.cs
ForceSeatMI API uses DLL which is installed as part of the ForceSeatPM software. Make sure that you have ForceSeatPM installed on your computer.

Application: position control

Examples:

  • TableLogPos_Unity shows positioning in abstract(logical, percentages) units
  • TablePhyPos_Unity 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. Import ForceSeatMI
    using MotionSystems;
  2. Create an API object variable inside your class:
    private ForceSeatMI m_fsmi;
  3. Initialize it in Start method:
    m_fsmi = new ForceSeatMI();
  4. If everything is loaded call:
    if (m_fsmi.IsLoaded())
    {
      m_fsmi.BeginMotionControl();
    }
  5. The SIM should send positioning data in constant intervals using one of the following functions:
    m_fsmi.SendTopTablePosLog(...);
    m_fsmi.SendTopTablePosPhy(...);
    m_fsmi.SendTopTableMatrixPhy(...);
  6. At the end of simulation call:
    if (m_fsmi.IsLoaded())
    {
      m_fsmi.EndMotionControl();
      m_fsmi.Dispose();
    }

Code

Below code comes from TableLogPos_Unity example.

// FSMI api
private ForceSeatMI m_fsmi;
 
// Position in logical coordinates that will be send to the platform
private FSMI_TopTablePositionLogical m_platformPosition = new FSMI_TopTablePositionLogical();
 
void Start ()
{
  // Load ForceSeatMI library from ForceSeatPM installation directory
  // ForceSeatMI - BEGIN
  m_fsmi = new ForceSeatMI();
 
  if (m_fsmi.IsLoaded())
  {
    // Find platform's components
    m_shaft = GameObject.Find("Shaft");
    m_board = GameObject.Find("Board");
 
    SaveOriginPosition();
    SaveOriginRotation();
 
    // Prepare data structure by clearing it and setting correct size
    m_platformPosition.mask = 0;
    m_platformPosition.structSize = (byte)Marshal.SizeOf(m_platformPosition);
 
    m_platformPosition.state = FSMI_State.NO_PAUSE;
 
    // Set fields that can be changed by demo application
    m_platformPosition.mask = FSMI_POS_BIT.STATE | FSMI_POS_BIT.POSITION;
 
    m_fsmi.BeginMotionControl();
 
    SendDataToPlatform();
    // ForceSeatMI - END
  }
  else
  {
    Debug.LogError("ForceSeatMI library has not been found!Please install ForceSeatPM.");
  }
}
 
void OnDestroy()
{
  // ForceSeatMI - BEGIN
  if (m_fsmi.IsLoaded())
  {
    m_fsmi.EndMotionControl();
    m_fsmi.Dispose();
  }
  // ForceSeatMI - END
}
 
private void SendDataToPlatform()
{
  // Convert parameters to logical units
  // ForceSeatMI - BEGIN
  m_platformPosition.state = FSMI_State.NO_PAUSE;
  m_platformPosition.roll = (short)Mathf.Clamp(m_roll / DRAWING_ROLL_MAX * PLATFORM_POSITION_LOGIC_MAX, PLATFORM_POSITION_LOGIC_MIN, PLATFORM_POSITION_LOGIC_MAX);
  m_platformPosition.pitch = (short)Mathf.Clamp(m_pitch / DRAWING_PITCH_MAX * PLATFORM_POSITION_LOGIC_MAX, PLATFORM_POSITION_LOGIC_MIN, PLATFORM_POSITION_LOGIC_MAX);
  m_platformPosition.heave = (short)Mathf.Clamp(m_heave / DRAWING_HEAVE_MAX * PLATFORM_POSITION_LOGIC_MAX, PLATFORM_POSITION_LOGIC_MIN, PLATFORM_POSITION_LOGIC_MAX);
 
  // Send data to platform
  m_fsmi.SendTopTablePosLog(ref m_platformPosition);
  // ForceSeatMI - END
}

Application: vehicle simulation

Examples: Telemetry_Veh_Unity (use built-in ForceSeatPM profile SDK – Vehicle Telemetry ACE)
Recommended reading: ForceSeatMI and ACE in vehicle physics simulation application

For vehicle simulation application ForceSeatMI_Vehicle helper interface can be used. Typical operation routine consists of following steps:

  1. Create an API object variable inside your class:
    private ForceSeatMI_Unity m_Api;
    private ForceSeatMI_Vehicle m_vehicle;
  2. Initialize it in Start method:
    m_Api = new ForceSeatMI_Unity();
    m_vehicle = new ForceSeatMI_Vehicle(m_Rigidbody)
  3. Call:
    m_Api.Begin();
  4. The SIM should send telemetry data in constant intervals using following function::
    m_Api.Update(...);
  5. At the end of simulation call:
    m_Api.End();

Code

Below code comes from Telemetry_Veh_Unity example.

private void Start()
{
  m_Rigidbody = GetComponent();
  // ForceSeatMI - BEGIN
  m_Api             = new ForceSeatMI_Unity();
  m_vehicle         = new ForceSeatMI_Vehicle(m_Rigidbody);
 
  m_vehicle.SetGearNumber(m_CurrentGearNumber);
 
  m_Api.SetAppID(""); // If you have dedicated app id, remove ActivateProfile calls from your code
  m_Api.ActivateProfile("SDK - Vehicle Telemetry ACE");
  m_Api.SetTelemetryObject(m_vehicle);
  m_Api.Pause(false);
  m_Api.Begin();
  // ForceSeatMI - END
}
 
private void OnDestroy()
{
  // ForceSeatMI - BEGIN
  m_Api.End();
  // ForceSeatMI - END
}
 
private void Move(float steering, float accel, float footbrake, float handbrake)
{
  ...
 
  // ForceSeatMI - BEGIN
  if (m_vehicle != null && m_Api != null)
  {
    m_vehicle.SetGearNumber(m_CurrentGearNumber);
    m_Api.AddExtra(m_extraParameters);
    m_Api.Update(Time.fixedDeltaTime);
  }
  // ForceSeatMI - END
}

Application: flight simulation

Examples: Telemetry_Fly_Unity (use built-in ForceSeatPM profile SDK – Plane Telemetry ACE)
Recommended reading: ForceSeatMI and ACE in plane physics simulation application

For flight simulation application ForceSeatMi_UnityAeroplane helper interface can be used. Typical operation routine consists of following steps:

  1. Create an API object variable inside your class:
    private ForceSeatMI_Unity m_Api;
    private ForceSeatMI_Aeroplane m_aeroplane;
  2. Initialize it in Start method:
    m_Api = new ForceSeatMI_Unity();
    m_aeroplane = new ForceSeatMI_Aeroplane(m_Rigidbody)
  3. Call:
    m_Api.Begin();
  4. The SIM should send telemetry data in constant intervals using following function:
     m_Api.Update(...);
  5. At the end of simulation call:
    m_Api.End();

Code

Below code comes from Telemetry_Fly_Unity example.

private void Start()
{
  m_Rigidbody = GetComponent();
 
  // ForceSeatMI - BEGIN
  m_Api = new ForceSeatMI_Unity();
  m_aeroplane = new ForceSeatMI_Aeroplane(m_Rigidbody);
 
  m_Api.SetAppID(""); // If you have dedicated app id, remove ActivateProfile calls from your code
  m_Api.ActivateProfile("SDK - Plane Telemetry ACE");
  m_Api.SetTelemetryObject(m_aeroplane);
  m_Api.Pause(false);
  m_Api.Begin();
  // ForceSeatMI - END
}
 
private void OnDestroy()
{
  // ForceSeatMI - BEGIN
  m_Api.End();
  // ForceSeatMI - END
}
 
private void FixedUpdate()
{
  ...
 
  // ForceSeatMI - BEGIN
  m_Api.Update(Time.fixedDeltaTime);
  // ForceSeatMI - END
}

Upgrade to newer Unity version

Samples delivered with ForceSeatMI were created in older Unity version. When newer Unity loads them, an upgrade is performed. When upgraded project is loaded into Unity first time, it usually reports an error.

Make sure to click Ignore.

Missing ‘Registry’ component

If there is an error related to missing Registry component in ForceSeatMI.cs, then there are two solutions for it:

  • you can remove routine that check Windows Registry to get path to ForceSeatPM installation and put hardcoded path directly in the code (not recommended)
  • you can switch the project to use .NET 4.x instead of NET Standard 2.0

Go to Project Settings and change Api Compatibility Level.


Related articles

You might be interested in following articles. If you want download SDK or purchase it, please visit product page.