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.