Graphics.RotMatrixDataPlayback - lordmundi/wikidoctest GitHub Wiki

Rot Matrix Data Playback

This is a method that shows how you can grab data from a rotation matrix using the simdata plugin and use it to drive the PYR of a node in graphics.

NOTE: This only applies if you are using the simdata plugin for post-sim visualization, and you don't have euler angles available. If you are driving the graphics live with a sim, matrix functions are directly available for this. Also, if you can re-record the sim, record euler angles and avoid all this. But, if you have rotation matrices that you want to tie to a node using the simdata plugin, read on.

This relies on the math_utils_library.tcl file that has the update applied in Issue 00076. If you don't have the updated library, let us know so we can get it to you, or get a later version of EDGE which has the update.

Here is an example of using a rotation matrix to drive the attitude of HTV (This assumes you already have the nodes set up to drive an orbital body, such as the SIM_POS and SIM_ATT nodes, as described [Graphics.OrbitalSimIntegration|here]]):

Step 1: Add lines into your API file to load each of the rows of the matrix into the PYR of 3 new nodes.

HTV_SIM_ATT1 graphics.htv.out.T_ecef_gmf[0][0]  pitch  d   write  1.0
HTV_SIM_ATT1 graphics.htv.out.T_ecef_gmf[0][1]  yaw    d   write  1.0
HTV_SIM_ATT1 graphics.htv.out.T_ecef_gmf[0][2]  roll   d   write  1.0
HTV_SIM_ATT2 graphics.htv.out.T_ecef_gmf[1][0]  pitch  d   write  1.0
HTV_SIM_ATT2 graphics.htv.out.T_ecef_gmf[1][1]  yaw    d   write  1.0
HTV_SIM_ATT2 graphics.htv.out.T_ecef_gmf[1][2]  roll   d   write  1.0
HTV_SIM_ATT3 graphics.htv.out.T_ecef_gmf[2][0]  pitch  d   write  1.0
HTV_SIM_ATT3 graphics.htv.out.T_ecef_gmf[2][1]  yaw    d   write  1.0
HTV_SIM_ATT3 graphics.htv.out.T_ecef_gmf[2][2]  roll   d   write  1.0

Step 2: Add the nodes into the scene, probably using userdata/configs/user_models.cfg. The "ATT" node without a number will be the actual node that is driven.

node(HTV_SIM_ATT1); parent( NULL );
                node(HTV_SIM_ATT2); parent( NULL );
                node(HTV_SIM_ATT3); parent( NULL );
                node(ISS_SIM_ATT1); parent( NULL );
                node(ISS_SIM_ATT2); parent( NULL );
                node(ISS_SIM_ATT3); parent( NULL );

Step 3: Add in a script that will drive the att node after gathering the data from the 3 nodes holding the rotation matrix data and converting it to euler angles. Here is an example:

#!/usr/bin/wish

set htv_row_1_node "HTV_SIM_ATT1"
set htv_row_2_node "HTV_SIM_ATT2"
set htv_row_3_node "HTV_SIM_ATT3"
set htv_att_node   "HTV_SIM_ATT"

set htv_row_1_fresh 0
set htv_row_2_fresh 0
set htv_row_3_fresh 0

doug.display set -format "%0.6f"
doug.callback add update update_htv_attitude
doug.callback add update -nodes $htv_row_1_node "set htv_row_1_fresh 1"
doug.callback add update -nodes $htv_row_2_node "set htv_row_2_fresh 1"
doug.callback add update -nodes $htv_row_3_node "set htv_row_3_fresh 1"

# math interface routines...
if { [catch { source "$env(DOUG_HOME)/gui/interface_libraries/math_utils_library.tcl" } results] != 0 } {
    puts "ERROR sourcing $env(DOUG_HOME)/gui/interface_libraries/math_utils_library.tcl: ${results}"
    exit -1
}

proc update_htv_attitude { } {
    global RTD
    global htv_row_1_fresh htv_row_2_fresh htv_row_3_fresh
    global htv_row_1_node htv_row_2_node htv_row_3_node
    global htv_att_node

    set htv_rot_mat {}
    set htv_pyr {}

    # If we have fresh data on all 3 rows, compute PYR and drive
    if { $htv_row_1_fresh && $htv_row_2_fresh && $htv_row_3_fresh } {
        # First get the elements loaded into the rot matrix for HTV
        lappend htv_rot_mat [doug.node $htv_row_1_node get -pitch]
        lappend htv_rot_mat [doug.node $htv_row_1_node get -yaw  ]
        lappend htv_rot_mat [doug.node $htv_row_1_node get -roll ]
        lappend htv_rot_mat [doug.node $htv_row_2_node get -pitch]
        lappend htv_rot_mat [doug.node $htv_row_2_node get -yaw  ]
        lappend htv_rot_mat [doug.node $htv_row_2_node get -roll ]
        lappend htv_rot_mat [doug.node $htv_row_3_node get -pitch]
        lappend htv_rot_mat [doug.node $htv_row_3_node get -yaw  ]
        lappend htv_rot_mat [doug.node $htv_row_3_node get -roll ]

        # Convert the rotation matrix into euler angles
        set htv_pyr [deuler_231 $htv_rot_mat 1]
        set htv_p [expr [lindex $htv_pyr 0] * $RTD]
        set htv_y [expr [lindex $htv_pyr 1] * $RTD]
        set htv_r [expr [lindex $htv_pyr 2] * $RTD]

        # Drive the node
        doug.node $htv_att_node set -pitch $htv_p -yaw $htv_y -roll $htv_r

        # Reset flags
        set htv_row_1_fresh 0; set htv_row_2_fresh 0; set htv_row_3_fresh 0
    }
}

Step 4: Add that script to your user.cfg in your GUI block. If you are not familiar with doing this, read about Display Contexts.