NDEVR
API Documentation
TotalStationNoiseSimulator.h
1#pragma once
2#include <NDEVR/GenericOption.h>
3#include <NDEVR/BaseValues.h>
4#include <NDEVR/Random.h>
5#include <NDEVR/Time.h>
6#include <NDEVR/TimeSpan.h>
7#include <NDEVR/UnitDefinitions.h>
8#include <NDEVR/Angle.h>
9#include <NDEVR/AngleDefinitions.h>
10#include <NDEVR/Translator.h>
11#include "DLLInfo.h"
12namespace NDEVR
13{
20 //Vernier Acuity: Eye reference accuracy,
21 //parallax:
23 //Vector<2, Angle<fltp08>> optical_axis = Vector<2, Angle<fltp08>>();
24 //for displacement (e) of encoder ring radius (r) the error is
25 Vector<2, fltp08> v_circle_eccentricity = Vector<2, fltp08>(0.0, 1.2e-5);
26 Vector<2, fltp08> h_circle_eccentricity = Vector<2, fltp08>(0.0, 1.2e-5);
27 fltp08 encoder_radius = 0.005;
28 Vector<2, fltp08> optical_axis = Vector<2, fltp08>(0.0, 1.2e-5);
30 Angle<fltp08>(DEGREES, 0.01638888888)
31 , Angle<fltp08>(DEGREES, 0.06 / 60.0 / 60));//goniometer
33 Angle<fltp08>(DEGREES, 0.01638888888)
34 , Angle<fltp08>(DEGREES, 0.06 / 60.0 / 60));//goniometer
35 //Angle<fltp08> δπ = Angle<fltp08>(RADIANS, 0.001);
36 //standing axis (SA) and trunnion axis (TA)
37 class TOTAL_STATION_API TotalStationNoiseSimulator
38 {
39 public:
40 template<uint01 t_dims, class t_type>
41 void addVector(GenericOptionGroup& group, const Vector<t_dims, t_type>& vector, const StringView name, ConstPointer<Unit> unit = ConstPointer<Unit>())
42 {
43 for (uint04 i = 0; i < t_dims; i++)
44 {
45 String axis_name(name);
46 axis_name = axis_name.toLower();
47 axis_name.replaceAll(' ', '_');
48 axis_name.append('_');
49 switch (i)
50 {
51 case 0: axis_name.append("Hz"); break;
52 case 1: axis_name.append("V"); break;
53 default: axis_name.append(cast<char>('x' + i)); break;
54 }
55
56 GenericOption option(axis_name, TranslatedString::DirectString(axis_name.toTitleString()), cast<fltp04>(vector[i]));
57 //option.dec
58 option.unit = unit;
59 group.addOption(option);
60 }
61 }
62 template<uint01 t_dims, class t_type>
63 void setVector(const GenericOptionGroup& group, Vector<t_dims, t_type>& vector, const StringView name)
64 {
65 for (uint04 i = 0; i < t_dims; i++)
66 {
67 String axis_name(name);
68 axis_name = axis_name.toLower();
69 axis_name.replaceAll(' ', '_');
70 axis_name.append('_');
71 switch (i)
72 {
73 case 0: axis_name.append("Hz"); break;
74 case 1: axis_name.append("V"); break;
75 default: axis_name.append(cast<char>('x' + i)); break;
76 }
77 vector[i] = group.getValue<fltp08>(axis_name);
78 }
79 }
80 Buffer<GenericOptionGroup> groups()
81 {
82 Buffer<GenericOptionGroup> options;
83
84 GenericOptionGroup camera(_t("Camera"));
85 camera.addOption(GenericOption("camera_fov", _t("Camera FOV"), camera_fov));
86 options.add(camera);
87 //Gyroscope noise and bias parameters
88 GenericOptionGroup theodolite(_t("Errors"));
89 addVector(theodolite, v_circle_eccentricity, "vertical_circle_eccentricity", UnitDefinitions::Micron());
90 addVector(theodolite, h_circle_eccentricity, "horizontal_circle_eccentricity", UnitDefinitions::Micron());
91 GenericOption encoder_radius("encoder_radius", _t("Encoder Ring Radius"), encoder_radius);
92 encoder_radius.unit = UnitDefinitions::Millimeters();
93 theodolite.addOption(encoder_radius);
94 addVector(theodolite, optical_axis, "optical_axis", UnitDefinitions::DegreesMinutesSeconds());
95 addVector(theodolite, optical_collimation, "collimation", UnitDefinitions::DegreesMinutesSeconds());
96 addVector(theodolite, trunation, "trunation", UnitDefinitions::DegreesMinutesSeconds());
97 options.add(theodolite);
98
99
100 return options;
101 // Magnetometer noise parameters (WARNING: Datasheet is incomplete for noise density and bias, this is a best guess)
102 /*fltp08 mag_noise_density_mean_ugauss_rt_hz = 80;
103 fltp08 mag_noise_density_std_ugauss_rt_hz = 80;
104 Vector<3, fltp08> mag_bias_gauss = Vector<3, fltp08>(0.0);
105 fltp08 mag_bias_offset_mean_ugauss = 0.0016;
106 fltp08 mag_bias_offset_std_ugauss = 0.0016;
107 fltp08 max_mag_bias_offset_gauss = 0.0085;*/
108 }
109
110 void saveGyroSettings(File file)
111 {
112 Buffer<GenericOptionGroup> settings = groups();
113 INIFactory gyro_factory;
114 gyro_factory.setPreserveOrder(true);
115 settings[0].addOptionsToINI(gyro_factory);
116 gyro_factory.writeToAsciiFile(file);
117 }
118 void saveAccelerometerSettings(File file)
119 {
120 Buffer<GenericOptionGroup> settings = groups();
121 INIFactory acc_factory;
122 acc_factory.setPreserveOrder(true);
123 settings[1].addOptionsToINI(acc_factory);
124 acc_factory.writeToAsciiFile(file);
125 }
126 void loadGyroSettings(File file)
127 {
128 Buffer<GenericOptionGroup> settings = groups();
129 INIFactory gyro_factory;
130 gyro_factory.setPreserveOrder(true);
131 settings[0].addOptionsToINI(gyro_factory);
132 gyro_factory.readAsciiFile(file);
133 }
134 void loadAccelerometerSettings(File file)
135 {
136 Buffer<GenericOptionGroup> settings = groups();
137 INIFactory acc_factory;
138 acc_factory.setPreserveOrder(true);
139 settings[1].addOptionsToINI(acc_factory);
140 acc_factory.readAsciiFile(file);
141 }
142 TotalStationNoiseSimulator()
143 : m_random_number_generator(Time::SystemTime().getNanoSeconds() % 100000)//random seed
144 {
145 }
146 void setTemperature(fltp08 temperature)
147 {
148 //TODO: Adjust any needed variables
149 m_temperature = temperature;
150 }
151
152 private:
153 // Internal state tracking
154 Vector<3, fltp08> m_current_gyro_scale_error = Vector<3, fltp08>(0.0);
155 Vector<3, fltp08> m_current_accel_bias_instability = Vector<3, fltp08>(0.0);
156 Vector<3, fltp08> m_gyro_bias_dph = Vector<3, fltp08>(0.0); // Current gyro bias per axis in deg/hr
157 Vector<3, fltp08> m_accel_bias = Vector<3, fltp08>(0.0); // Current accel bias per axis in ug
158 Vector<3, fltp08> m_accel_scale_error = Vector<3, fltp08>(0.0);
159 GaussianRN<> m_random_number_generator;//Used to generate random gausian numbers by calling randonumber_generator.get()
160 Time m_last_gyro_update_time = Constant<Time>::Invalid;
161 Time m_last_accelerometer_update_time = Constant<Time>::Invalid;
162 Time m_last_magnetometer_update_time = Constant<Time>::Invalid;
163 fltp08 m_temperature = 30.0;//temperature in celsius. Can be adjusted in the simulation.
164 };
165}
Stores an angle in an optimized internal format with support for efficient trigonometric operations.
Definition Angle.h:83
Provides a constant, unmodifiable pointer that has shared ownership of a dynamically allocated object...
Definition Pointer.hpp:276
Stores a groups of GenericOptions that can be used to group them.
void addOption(const TranslatedString &name, const t_type &value, bool is_editable=true)
Adds a new option to this group with the given name and typed value.
The core String View class for the NDEVR API.
Definition StringView.h:58
The core String class for the NDEVR API.
Definition String.h:95
A fixed-size array with N dimensions used as the basis for geometric and mathematical types.
Definition Vector.hpp:62
The primary namespace for the NDEVR SDK.
Angle< fltp08 > camera_fov
This class generates random bias and noise for modeling a 9-DoF IMU.
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
double fltp08
Defines an alias representing an 8 byte floating-point number.
@ DEGREES
Angle measured in degrees (0 to 360 for a full circle).
Definition Angle.h:58
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
Definition Angle.h:408