Static-aiding
In this example, position, velocity, and attitude data is sent to an OxTS INS in real time, or saved as a GAD file for postprocessing. The full source code for the GAD SDK in both C++ and Python is shown below.
Requirements
An OxTS INS with the relevant Generic Aiding Feature Codes enabled. If you are not sure whether you have the right Feature Codes or are unfamiliar with them, contact support@oxts.com.
A PC, connected to the INS via ethernet.
The GAD SDK has been built on this machine.
How to run the executable
Navigate to the relevant project configuration directory in the build folder: cd <build_dir>/examples/gal.
Run the executable: ./static-aiding-example. This will begin sending Generic Aiding packets. There are four possible optional arguments that can be provided:
Device IP address
Number of packets
Output type (csv)
Output file (if outputting to csv)
For example: ./static-aiding-example 192.168.25.10 70 csv debug_out.csv will output 70 packets of data to debug_out.csv. To output to a live device omit the final 2 arguments: ./static-aiding-example 192.168.25.10 70
Navigate to the relevant directory in the build folder: cd <build_dir>/examples/gal/Debug.
From the command line run the executable: static-aiding-example.exe. This will begin sending Generic Aiding packets. There are four possible optional arguments that can be provided:
Device IP address
Number of packets
Output type (csv)
Output file (if outputting to csv)
For example: static-aiding-example.exe 192.168.25.10 70 csv debug_out.csv will output 70 packets of data to debug_out.csv. To output to a live device omit the final 2 arguments: static-aiding-example.exe 192.168.25.10 70
Source code
#include <iostream>
#include <string>
#include "oxts/gal-cpp/gad.hpp"
#include "oxts/gal-cpp/gad_handler.hpp"
#include "oxts_sleep.hpp"
enum class OUTPUT_TYPE
{
UDP = 0,
CSV = 1
};
int main(int argc, char* argv[])
{
int num_packets = 30;
std::string unit_ip = "192.168.25.22";
std::string file_out = "out.gad";
OUTPUT_TYPE output_type = OUTPUT_TYPE::UDP;
if (argc > 1)
{
unit_ip = argv[1];
}
if (argc > 2)
{
num_packets = std::stoi(argv[2]);
}
if (argc > 3)
{
if (!strcmp(argv[3], "csv"))
{
output_type = OUTPUT_TYPE::CSV;
}
}
if (argc > 4)
{
file_out = argv[4];
}
OxTS::Gal_Cpp::GadPosition gp(129);
gp.SetPosGeodetic(51.91520330,-1.24479140,111.525);
gp.SetPosGeodeticVar(1.0,1.0,1.0);
gp.SetTimeVoid();
gp.SetAidingLeverArmFixed(0.5,0.5,1.0);
gp.SetAidingLeverArmVar(0.1,0.1,0.1);
OxTS::Gal_Cpp::GadVelocity gv(130);
gv.SetVelNed(0.0,0.0,0.0);
gv.SetVelNedVar(0.1,0.1,0.1);
gv.SetTimeVoid();
gv.SetAidingLeverArmFixed(0.5,0.5,1.0);
gv.SetAidingLeverArmVar(0.1,0.1,0.1);
OxTS::Gal_Cpp::GadAttitude ga(131);
ga.SetAtt(0.0,0.0,0.0);
ga.SetAttVar(0.1,0.1,0.1);
ga.SetTimeVoid();
ga.SetAidingAlignmentOptimising();
ga.SetAidingAlignmentVar(5.0,5.0,5.0);
OxTS::Gal_Cpp::GadHandler gh;
switch (output_type)
{
case OUTPUT_TYPE::UDP:
gh.SetEncoderToBin();
gh.SetOutputModeToUdp(unit_ip);
break;
case OUTPUT_TYPE::CSV:
gh.SetEncoderToCsv();
gh.SetOutputModeToFile(file_out);
break;
default:
std::cout << "Output type not known." << std::endl;
break;
}
for (int i = 0; i < num_packets; ++i)
{
gh.SendPacket(gp);
gh.SendPacket(gv);
gh.SendPacket(ga);
if (i % 10 == 0)
{
std::cout << i << " packets sent" << std::endl;
}
OxTS::sleep_milliseconds(100);
}
return 0;
}
import sys
import time
import oxts_sdk
from enum import Enum
class OUTPUT_TYPE(Enum):
UDP = 0
CSV = 1
if __name__ == "__main__":
# defaults
num_packets = 30
unit_ip = "192.168.25.22"
file_out = "out.gad"
output_type = OUTPUT_TYPE.UDP
if len(sys.argv) > 1:
unit_ip = sys.argv[1]
if len(sys.argv) > 2:
num_packets = sys.argv[2]
if len(sys.argv) > 3:
if sys.argv[3].lower()== 'csv':
output_type = OUTPUT_TYPE.CSV
if len(sys.argv) > 4:
file_out = sys.argv[4]
gp = oxts_sdk.GadVPosition(129)
gp.pos_geodetic = [51.91520330,-1.24479140,111.525]
gp.pos_geodetic_var =[ 1.0,1.0,1.0]
gp.set_time_void()
gp.aiding_lever_arm_fixed = [0.5,0.5,1.0]
gp.aiding_lever_arm_var = [0.1,0.1,0.1]
gv = oxts_sdk.GadVelocity(129)
gv.vel_ned = [0.0,0.0,0.0]
gv.vel_ned_var = [0.1,0.1,0.1]
gv.set_time_void()
gv.aiding_lever_arm_fixed = [0.5,0.5,1.0]
gv.aiding_lever_arm_var = [0.5,0.5,1.0]
ga = oxts_sdk.GadAttitude(131)
ga.att = [0.0,0.0,0.0]
ga.att_var = [0.1,0.1,0.1]
ga.set_time_void()
ga.aiding_alignment_fixed = [90.0, 1.0, 0.0]
ga.aiding_alignment_var = [5.0,5.0,5.0]
gh = oxts_sdk.GadHandler()
if output_type == OUTPUT_TYPE.UDP:
gh.set_encoder_to_bin()
gh.set_output_mode_to_udp(unit_ip)
elif output_type == OUTPUT_TYPE.CSV:
gh.set_encoder_to_csv()
gh.set_output_mode_to_to_file(file_out)
else:
print("Output type not known.")
sys.exit(1)
for i in range(0,num_packets,1):
# Send the packets
gh.send_packet(gp)
gh.send_packet(gv)
gh.send_packet(ga)
if (i % 10 == 0):
print("packet " + str(i) + " sent")
time.sleep(0.1)
sys.exit(0)
Code breakdown
Since a lot of the code seen here is the same as shown previously, we will concentrate on specific sections that show new functionality.
enum class OUTPUT_TYPE
{
UDP = 0,
CSV = 1
};
class OUTPUT_TYPE(Enum):
UDP = 0
CSV = 1
This is a simple enum, to allow switching between UDP (via ethernet) and CSV (file) output.
int num_packets = 30;
std::string unit_ip = "192.168.25.22";
std::string file_out = "out.gad";
OUTPUT_TYPE output_type = OUTPUT_TYPE::UDP;
if (argc > 1)
{
unit_ip = argv[1];
}
if (argc > 2)
{
num_packets = std::stoi(argv[2]);
}
if (argc > 3)
{
if (!strcmp(argv[3], "csv"))
{
output_type = OUTPUT_TYPE::CSV;
}
}
if (argc > 4)
{
file_out = argv[4];
}
# defaults
num_packets = 30
unit_ip = "192.168.25.22"
file_out = "out.gad"
output_type = OUTPUT_TYPE.UDP
if len(sys.argv) > 1:
unit_ip = sys.argv[1]
if len(sys.argv) > 2:
num_packets = sys.argv[2]
if len(sys.argv) > 3:
if sys.argv[3].lower()== 'csv':
output_type = OUTPUT_TYPE.CSV
if len(sys.argv) > 4:
file_out = sys.argv[4]
The first half of this section sets the default values for the four input arguments of the main function. The four input arguments are (in order):
IP address of the INS unit
Number of measurement packets to be converted into GAD packets (default = 30).
Type of output to be sent. If this is “csv” or “CSV” then the output will be saved as a GAD file. Otherwise, it will be sent to the unit via UDP.
If the output is to be saved as a GAD file, then this is the name of GAD file. (default is “out.gad”).
The second half of this section reads in and sets the input arguments listed above.
switch (output_type)
{
case OUTPUT_TYPE::UDP:
gh.SetEncoderToBin();
gh.SetOutputModeToUdp(unit_ip);
break;
case OUTPUT_TYPE::CSV:
gh.SetEncoderToCsv();
gh.SetOutputModeToFile(file_out);
break;
default:
std::cout << "Output type not known." << std::endl;
break;
}
gh = oxts_sdk.GadHandler()
if output_type == OUTPUT_TYPE.UDP:
gh.set_encoder_to_bin()
gh.set_output_mode_to_udp(unit_ip)
elif output_type == OUTPUT_TYPE.CSV:
gh.set_encoder_to_csv()
gh.set_output_mode_to_to_file(file_out)
else:
print("Output type not known.")
sys.exit(1)
This block of code initialises an instance of the GadHandler and sets it up to either send Generic Aiding data via UDP or to CSV file, based on the configuration option at the start of the file.
Exercise
Set-up the equipment on a work bench; remember that for this example, no sensor is needed.
Configure and initialise the INS. How will you initialise the INS if it is mounted on a work bench?
Enter in the position given by the navigation engine into the GAD SDK program.
Run the executable (C++) or run the code from the Python command line. Make sure the output type is set to UDP.
Observe the output of the Navigation engine with NAVDisplay. Remember that the GAD SDK is feeding the navigation engine that give no movement. So, what happens when you move the INS across the work desk?
Now try to the output type to csv and rerun the GAD SDK. After the program has finished (run out of packets to send), look at the GAD file with a spreadsheet program such as Excel. Do you understand the information given in this GAD file? See here for more information on the format of gad files.
You will notice that in the GAD SDK code, the different update types are made outside of the packet loop. Move the code for one of the update types, e.g. velocity, into the packet loop section. Now write a function that varies the input value, e.g. the velocity could be the square root of the packet number. Run the GAD SDK program again (output type = csv), study the GAD file. Do you see where the values in the gad file have changed?