All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.nps.moves.deadreckoning.DIS_DeadReckoning Maven / Gradle / Ivy

Go to download

An open source implementation of the Distributed Interactive Simulation (DIS) IEEE-1278 protocol

There is a newer version: 5.8
Show newest version
package edu.nps.moves.deadreckoning;

import edu.nps.moves.deadreckoning.utils.*;

/**
 * The root super class for all DIS Dead-Reckoning algorithms.
 * Based on the algrorithms from the 
 * IEEE 1278_1-1995_DIS standards found in 
 * Annex B.
 * 

*


*

* Final project presentation *

*


*

* Creates an abstract instance of a Dead Reckoning (DR) algorithm, defined * by the concrete Dead Reckoning algorithm on the right hand side. *

* At each PDU update received, call the set function to update the DR * algorithm with the most accurance and update information. Expected to receive * a new update approx every 5 seconds or so. Each PDU is essentally a * restart or reset of the DR state. *

* The DR wroks off the last good state (origin) and extrapulates out from that * point based on the velocity and acceleration parameters from the set * function. *

* The DR algorithm updates 30 times a second. The instantiating entity * can get updated DR states at its leasure upto 30 times a second by calling * the get function, which returns an array of 6 doubles 3 x location and * 3 x orientation. With these 6 parameters the entity can redraw itslef in an * updatedloation and orientsation based on its projected path. *

*


*

*

Keynotes form the IEEE DIS standard about DR

*

*

*

* DRM notation shall consist of three elements. * *

  • The First element shall indicate whether the model specifies * rotation as either fixed (F) or rotating (R).
  • *
  • The second element shall specify dead reckoning rates to be held * constant as either rate of position (P) or rate of velocity (V).
  • *
  • The third element shall specify the coordinate system to be used with * the dead reckoning algorithm as either world coordinates (W) or body axis * coordinates (B).
  • * *

    *


    *

    * 5.2.1 Angle representation
    * Angles shall be specfified as 32-bit floating point numbers expressed * in radians.(page 55) *

    * 5.2.2 Angular Velocity Vector record
    * The angular velocity of simulated entities shall be represented by the Angular * Velocity Vector record. This record shall specify the rate at which an * entity's orientation is changing. The angular velocity shall be measured * in radians per second measured about each of the entity's own * coordinate axes. The record shall consist of three fields. The first field * shall represent velocity about the x-axis, the second about the y-axis, and * the third about the z-axis [see 5.2.33 item a)]. The positive direction of * the angular velocity is defined by the right-hand rule. The format of the * Angular Velocity Vector record shall be shown as in table 5. (Page 55) *
    *

    *

    * 5.2.17 Euler Angles record
    * Orientation of a simulated entity shall be specified by the Euler Angles * record. This record shall specify three angles as described in figure 3 and * 3.1.13. These angles shall be specified with respect to the entity's * coordinate system. The three angles shall each be specified by a 32-bit * floating point number representing radians. The format of the Euler * Angles record shall be as shown in table 19. (page 65) *
    *

    *

    * 5.2.33 Vector record
    * Vector values for entity coordinates, linear acceleration, and linear * velocity, shall be represented using a Vector record. This record shall * consist of three fields, each a 32-bit floating point number. The unit of * measure represented by these fields shall depend on the information * represented. The values utilizing the Vector record are as follows: *

    * a) Entity Coordinate Vector. Location with respect to a particular entity * shall be specified with respect to three orthogonal axes whose origin shall * be the geometric center of the bounding volume of the entity excluding its * articulated and attached parts (see figure 2). The x-axis extends in the * positive direction out the front of the entity. The y-axis extends in the * positive direction out the right side of the entity as viewed from above, * facing in the direction of the positive x-axis. The z-axis extends in the * positive direction out the bottom of the entity. Each vector component * shall represent meters from the origin (see figure 2). *

    * b) Linear Acceleration Vector. Linear acceleration shall be represented as a * vector with components in either world coordinate system or entity's * coordinate system depending on the value in the Dead Reckoning Algorithm * field. Each vector component shall represent acceleration in meters per * second squared. *

    * c) Linear Velocity Vector. Linear velocity shall be represented as a vector * with three components in either world coordinate system or entity's * coordinate system depending on the value in the Dead Reckoning Algorithm * field. Each vector component shall represent velocity in meters per * second. The format of the Vector record shall be as shown in * table 30. (page 73) *
    *

    *

    * 5.2.34 World Coordinates record
    * Location of the origin of the entity's coordinate system shall be specified * by a set of three coordinates: X, Y, and Z. The shape of the earth shall be * specified using DMA TR 8350.2, 1987. The origin of the world coordinate * system shall be the centroid of the earth, with the X-axis passing through * the prime meridian at the equator, the Y-axis passing through 90° east * longitude at the equator, and the Z-axis passing through the north pole * (see figure 1). These coordinates shall represent meters from the centroid * of the earth. A 64-bit double precision floating point number shall represent * the location for each coordinate. *

    The format of the World Coordinates record shall be as shown in table * 31. (page 73) *
    *

    *

    * The Dead Reckoning parameters captured from each PDU *

    * *
    * * * * * *

    *


    *

    *

    The IEEE specified algorithms to compute the DR for Primary * Methods Group (1-5)

    *

    *


    *

    *

    REVISED POSITION
    *

    *


    *

    * * The Position portion of the algorithms
    *

    *
    * *

    *


    *

    *

    ORIENTATION SOLVER
    *

    * Ultimately, the PSI (rotation about the y-axis), THETA (rotation about the * z-axis), PHI (rotation about the x-axis) need to be in the range * of 0 - 2PI since the fields are in radians. *

    *


    *

    * * * The Orientation portion of the algorithms
    *

    *
    * *

    *


    *

    *

    DR MATRIX SOLVER
    *

    *


    *

    * * The generic DR matrix
    *

    *
    *
    * Graphics rotate (x,y,z) matrices *
    * Rotate X * Rotate Y * Rotate Z = [DR] *
    * ultimately what this is DR equation is doing but with a change of basis * from world to entity coordinates. *
    *

    * * The angular velocity Magnitude
    *

    *
    *

    * * * The SKEW matrix
    *

    *
    * * * The angular velocity Matrix
    *
    *
    *

    * NOTE - It was mentioned above that the angular velocities are contained in * the Entity State PDU as body axis velocities. However, if the angular * velocities are in terms of the Euler angles, then a transformation to body * axis angular velocities is needed. Thus the following transformation * formulas are given: *

    * * Body to Wrold Transformation
    *

    *
    * * World to Body Transformation
    *
    *
    *

    *


    *

    *

    R MATRIX SOLVER
    *

    *


    *

    * * Initial Orientation Matrix
    *

    *

    *


    *

    *

    REVISED ORIENTATION
    *

    *


    *

    * * Get the Revised Orientation
    *

    * * *

    *


    *

    *

    The IEEE specified algorithms to compute the DR for Secondary * Methods Group (6-9)

    *

    *


    *

    * Note: the Rotaion formula * where applicable is the same as that used in the Primary Methods Group (1-5), * as well is the equation for getting the * revised orientations. *

    * * General position formula
    *

    *

    * * R1 vector (though I am not sure what its really calculating)
    *

    * *

    * * R2 vector (though I am not sure what its really calculating)
    *

    *

    * * *

    *


    *

    * An Example:
    *

    import DIS.DeadReconing.*;
    
    public class runTest 
    {
        public static void main(String s[])
        {
            // create a DeadReconing Entity
            DIS_DeadReckoning dr = new DIS_DR_FPW_02();
    
            // make the arrays of location and other parameters
            //                loc      orien    lin V    Accel    Ang V
            double[] locOr = {2,3,4,   5,6,1,   1,2,1,   0,0,0,   0,0,0};
            
            // set the parameters
            dr.setNewAll(locOr);
            
            // Print out the current state
            System.out.println(dr.toString());
            System.out.println();
    
            try
            {
                // wait 1 second
                Thread.sleep(1000);
                
                // request an update from the DR algorith
                // should be original + 1 full value of other parameters
                // new position should be (3, 5, 5)
                double[] update = dr.getUpdatedPositionOrientation();
                
                // print the update to the screen
                System.out.println(dr.toString());        
            }
            catch(Exception e)
            {
                System.out.println("Unknow Error...?\n    " + e);
            }
            
            // terminate with exit to get out of the inf while loop
            System.exit(0);
        }
    }
    
    Resulting Output:
    Current State of this Entity:
        Entity Location = (2.0, 3.0, 4.0)
        Entity Orientation = (5.0, 6.0, 1.0)
        Entity Linear Velocity = (1.0, 2.0, 1.0)
        Entity Linear Acceleration = (0.0, 0.0, 0.0)
        Entity Angular Velocity = (0.0, 0.0, 0.0)
        Delta between updates = 0.033333335
    
    Current State of this Entity:
        Entity Location = (3.000000052154064, 5.000000104308128, 5.000000052154064)
        Entity Orientation = (5.0, 6.0, 1.0)
        Entity Linear Velocity = (1.0, 2.0, 1.0)
        Entity Linear Acceleration = (0.0, 0.0, 0.0)
        Entity Angular Velocity = (0.0, 0.0, 0.0)
        Delta between updates = 0.033333335
     
     
    
    * * @author Sheldon L. Snyder */ public abstract class DIS_DeadReckoning implements Runnable { /** * The entity's X coordinate location with double percision 64bit */ protected double entityLocation_X; /** * The entity's Y coordinate location with double percision 64bit */ protected double entityLocation_Y; /** * The entity's Z coordinate location with double percision 64bit */ protected double entityLocation_Z; /** * The X orientation of the entity with 32bit float */ protected float entityOrientation_psi; /** * The Y orientation of the entity with 32bit float */ protected float entityOrientation_theta; /** * The Z orientation of the entity with 32bit float */ protected float entityOrientation_phi; /** * The X linear velocity 32bit float */ protected float entityLinearVelocity_X = 0; /** * The Y linear velocity 32bit float */ protected float entityLinearVelocity_Y = 0; /** * The Z linear velocity 32bit float */ protected float entityLinearVelocity_Z = 0; /** * The linear X acceleration 32bit float */ protected float entityLinearAcceleration_X = 0; /** * The linear Y acceleration 32bit float */ protected float entityLinearAcceleration_Y = 0; /** * The linear Z acceleration 32bit float */ protected float entityLinearAcceleration_Z = 0; /** * The X angular velocity 32bit float */ protected float entityAngularVelocity_X = 0; /** * The Y angular velocity 32bit float */ protected float entityAngularVelocity_Y = 0; /** * The Z angular velocity 32bit float */ protected float entityAngularVelocity_Z = 0; /** * how may times per second to update this entity's positon */ protected float fps = 30; /** * How far to change the location/orientation per update */ protected float changeDelta = 1f/fps; /** * How many updates have occured ... only used for testing *

    * Reset to 0 with each call to setAll() */ protected int deltaCt = 0;// how many updates have been called /** * How long to wait between updates *

    * the delta between calls...how fast an entity will be updated *

      *
    1. Assumed a desired rate of 30 fps
    2. *
    3. Given from the standard that all parameters are in meters/s
    4. *
    5. To move 1 meter/second with 30 incriments = 1/30 Delta between updates *
    6. delay in milli seconds is 1/30 * 1000 || 1000 / 30
    7. * *

      * Note from Java Doc for JDK:
      * Causes the currently executing thread to sleep (temporarily cease * execution) for the specified number of milliseconds, subject to the * precision and accuracy of system timers and schedulers. The thread does * not lose ownership of any monitors. */ protected long stall = (long)(1000/fps); /** * Thread for the DR algorithm update timing (1/30 second) */ protected Thread aThread; /** * the inital orientation, constant between delta T * Only changes when a setNewAll is called */ Matrix initOrien = new Matrix(3); /** * SKEW matrix, constant between delta T * Only changes when a setNewAll is called * Only changes when a setNewAll is called */ Matrix skewOmega = new Matrix(3); /** * Angular velocity matrix, constant between delta T * Only changes when a setNewAll is called */ Matrix ww = new Matrix(3); /** * Angular velocity magnitude, constant between delta T * Only changes when a setNewAll is called */ double wMag; /** * Magnatutd of angular velocity squared */ double wSq; /** * Float of PI for moduls rounding as needed */ float myPI = 3.1415926f; /*************************************************************************** * Constructor for all DR algorithms... *

      * Each subclass DR algorithm has a no arguments constructor, but all it * does is call the super, i.e. this constructor, which establishes the * Thread */ public DIS_DeadReckoning() { aThread = new Thread(this); aThread.start(); }//DIS_DeadReckoning()------------------------------------------------------ /*************************************************************************** * Gets the revised position and orientation of this entity *

      * Applies the required DR formula to the initial position and orientation * of this entity and returns the updated locaiton and position. *

      * This function does not actually perform the computations, it only returns * the current state of the entity. The entity state is updated byt the * specified DR alorithm within the DR class behind the scenes. Updates are * crated every 1/30 seconds. *

        *
      1. Assume a desire of 30 fps
      2. *
      3. All parameters are in meters/s
      4. *
      5. to move 1 meter/second with 30 incriments = 1/30 Delta between updates * *

        * Only returns an array of location and orientation because that * is all that is needed to update the location of the entity. All other * DR inputs are parameters for solving the locaiton and orientation and so * are not returned, only set. *

        * Order of the retruned array elements *

          *
        1. entityLocation_X
        2. *
        3. entityLocation_Y
        4. *
        5. entityLocation_Z
        6. *
        7. entityOrientation_psi
        8. *
        9. entityOrientation_theta
        10. *
        11. entityOrientation_phi
        12. *
        *

        * @return - 6 doubles of location and orientation */ public double[] getUpdatedPositionOrientation() { double[] newLoc = {entityLocation_X, entityLocation_Y, entityLocation_Z, entityOrientation_psi, entityOrientation_theta, entityOrientation_phi}; return newLoc; }//getUpdatedPositionOrientation()------------------------------------------ /*************************************************************************** * Sets the refresh rate for the scene. *

        * Default is 30 but can be changed throught this function call * * @param frames - the number of updats per second to make */ public void setFPS(int frames) { fps = frames; changeDelta = 1/fps; }//setFPS(int frames)------------------------------------------------------- /*************************************************************************** * Set the parameters for this entity's DR function based on the most * recent PDU. *

        * This ic called by the entity anytime the entity receives an updated * ESPDU for this entity. *

        * This can be the first and initialization call or update. *

        * The folowing (triples) are set with each call: *

          *
        1. Entity Locaiton 64bit
        2. *
        3. Entity Orientation 32bit
        4. *
        5. Entity Linear Velocity 32bit
        6. *
        7. Entity Linear Acceleration 32bit
        8. *
        9. Entity Angular Velocity 32bit
        *

        * entityLocation_X = allDis[0];
        * entityLocation_Y = allDis[1];
        * entityLocation_Z = allDis[2];
        *

        * entityOrientation_psi = (float)allDis[3];
        * entityOrientation_theta = (float)allDis[4];
        * entityOrientation_phi = (float)allDis[5];
        *

        * entityLinearVelocity_X = (float)allDis[6];
        * entityLinearVelocity_Y = (float)allDis[7];
        * entityLinearVelocity_Z = (float)allDis[8];
        *

        * entityLinearAcceleration_X = (float)allDis[9];
        * entityLinearAcceleration_Y = (float)allDis[10];
        * entityLinearAcceleration_Z = (float)allDis[11];
        *

        * entityAngularVelocity_X = (float)allDis[12];
        * entityAngularVelocity_Y = (float)allDis[13];
        * entityAngularVelocity_Z = (float)allDis[14];
        *

        * DR fields from a PDU update or initial * * @param allDis - 15 double percisions representing the above in order of the above */ public void setNewAll(double[] allDis) throws Exception { entityLocation_X = allDis[0]; entityLocation_Y = allDis[1]; entityLocation_Z = allDis[2]; entityOrientation_psi = (float)allDis[3]; entityOrientation_theta = (float)allDis[4]; entityOrientation_phi = (float)allDis[5]; entityLinearVelocity_X = (float)allDis[6]; entityLinearVelocity_Y = (float)allDis[7]; entityLinearVelocity_Z = (float)allDis[8]; entityLinearAcceleration_X = (float)allDis[9]; entityLinearAcceleration_Y = (float)allDis[10]; entityLinearAcceleration_Z = (float)allDis[11]; entityAngularVelocity_X = (float)allDis[12]; entityAngularVelocity_Y = (float)allDis[13]; entityAngularVelocity_Z = (float)allDis[14]; // solve for magnatude wMag = Math.sqrt(entityAngularVelocity_X * entityAngularVelocity_X + entityAngularVelocity_Y * entityAngularVelocity_Y + entityAngularVelocity_Z * entityAngularVelocity_Z); wSq = wMag * wMag; //System.out.println("wMag print"); //System.out.println(wMag); //System.out.println(); // build the skew matrix setOmega(); //System.out.println("skewOmega print"); //skewOmega.print(); //System.out.println(); // build the angular velocity matrix setWW(); //System.out.println("ww print"); //ww.print(); //System.out.println(); // reset delta count given this new update setInitOrient(); //System.out.println("init Orient print"); //initOrien.print(); //System.out.println(); deltaCt = 0; }//setNewAll(double[] allDis)----------------------------------------------- /*************************************************************************** * With each setNewAll() makes the new initial orientation matrix given the * new parameters * @throws java.lang.Exception */ private void setInitOrient() throws Exception { double cosPsi = Math.cos(entityOrientation_psi); double sinPsi = Math.sin(entityOrientation_psi); double cosTheta = Math.cos(entityOrientation_theta); double sinTheta = Math.sin(entityOrientation_theta); double cosPhi = Math.cos(entityOrientation_phi); double sinPhi = Math.sin(entityOrientation_phi); initOrien.setCell(0, 0, cosTheta*cosPsi); initOrien.setCell(0, 1, cosTheta*sinPsi); initOrien.setCell(0, 2, -sinTheta); initOrien.setCell(1, 0, sinPhi*sinTheta*cosPsi - cosPhi*sinPsi); initOrien.setCell(1, 1, sinPhi*sinTheta*sinPsi + cosPhi*cosPsi); initOrien.setCell(1, 2, sinPhi*cosTheta); initOrien.setCell(2, 0, cosPhi*sinTheta*cosPsi + sinPhi*sinPsi); initOrien.setCell(2, 1, cosPhi*sinTheta*sinPsi - sinPhi*cosPsi); initOrien.setCell(2, 2, cosPhi*cosTheta); }//setInitOrient() throws Exception----------------------------------------- /*************************************************************************** * With each setNewAll() makes the new angular velocity matrix given the * new parameters * @throws java.lang.Exception */ private void setWW() throws Exception { ww.setCell(0, 0, entityAngularVelocity_X * entityAngularVelocity_X); ww.setCell(0, 1, entityAngularVelocity_X * entityAngularVelocity_Y); ww.setCell(0, 2, entityAngularVelocity_X * entityAngularVelocity_Z); ww.setCell(1, 0, entityAngularVelocity_Y * entityAngularVelocity_X); ww.setCell(1, 1, entityAngularVelocity_Y * entityAngularVelocity_Y); ww.setCell(1, 2, entityAngularVelocity_Y * entityAngularVelocity_Z); ww.setCell(2, 0, entityAngularVelocity_Z * entityAngularVelocity_X); ww.setCell(2, 1, entityAngularVelocity_Z * entityAngularVelocity_Y); ww.setCell(2, 2, entityAngularVelocity_Z * entityAngularVelocity_Z); }//setWW() throws Exception------------------------------------------------- /*************************************************************************** * With each setNewAll() makes the new skew matrix given the * new parameters * @throws java.lang.Exception */ private void setOmega() throws Exception { skewOmega.setCell(0, 0, 0); skewOmega.setCell(1, 1, 0); skewOmega.setCell(2, 2, 0); skewOmega.setCell(1, 0, entityAngularVelocity_Z); skewOmega.setCell(2, 0, -entityAngularVelocity_Y); skewOmega.setCell(2, 1, entityAngularVelocity_X); skewOmega.setCell(0, 1, -entityAngularVelocity_Z); skewOmega.setCell(0, 2, entityAngularVelocity_Y); skewOmega.setCell(1, 2, -entityAngularVelocity_X); }//setOmega() throws Exception---------------------------------------------- /*************************************************************************** * Pretty print the current state of this Dead Reckoning object *

        * Updates are not included in this call, this is only the state. * * @return - String of pretty print of this DR entity */ public String toString() { String buff = "Current State of this Entity:\n" + " Entity Location = (" + entityLocation_X + ", " + entityLocation_Y + ", " + entityLocation_Z + ")\n" + " Entity Orientation = (" + entityOrientation_psi + ", " + entityOrientation_theta + ", " + entityOrientation_phi + ")\n" + " Entity Linear Velocity = (" + entityLinearVelocity_X + ", " + entityLinearVelocity_Y + ", " + entityLinearVelocity_Z + ")\n" + " Entity Linear Acceleration = (" + entityLinearAcceleration_X + ", " + entityLinearAcceleration_Y + ", " + entityLinearAcceleration_Z + ")\n" + " Entity Angular Velocity = (" + entityAngularVelocity_X + ", " + entityAngularVelocity_Y + ", " + entityAngularVelocity_Z + ")\n" + " Delta between updates = " + changeDelta; return buff; }// toString()-------------------------------------------------------------- }// DIS_DeadReckoning-----------------------------------------------------------





    © 2015 - 2024 Weber Informatics LLC | Privacy Policy