OVMS Plus Software Notes
The "OVMS+" project is an enhancement to the
OVMS software to provide OPD estimation in real-time to instruments. It was implemented by Michael Boem and Jose Borelli.
Design
Initially it was discussed whether to send the estimates as a separate real-time broadcast, or together with the accelerometer data. There was concern that it would no longer meet the 4kHz requirement if we included more calculations into the real-time stream. After some testing at MPIA, they found:
Subject: AW: Minutes of OVMS+ teleconference
Date: Thu, 22 Oct 2015 11:53:28 +0200
From: Böhm, Michael <michael.boehm@isys.uni-stuttgart.de>
Dear All,
We did some tests at the UEI-Unit we have at MPIA in Heidelberg yesterday.
Since we only have 2 cards, we interpolated the additional time needed for all 12 cards from the difference of using 1 and 2 cards, respectively.
I state now the option (see minutes) and the maximum possible rate for the RackTangle that can be expected:
Option a (3 values): 2430 Hz
Option b (5values): 2200 Hz
Option c (18 vlaues): 1350 Hz
For Option c, tip, tilt and opd were calculated for each mirror separately. It did not seem to make a big difference if we send these calculated values or not.
Maybe we can organize the code better as to gain a few µs of execution time. We have not tried any optimization (except for compiler flags, which did not improve anything).
Anyway, I think these results are promising and we can go for option 1, which means broadcasting accelerometer values and the additional values all at once.
Maybe we can add an option with no calculation at all, which would preserve the original functionality.
This way the requirements won't have to be touched.
Please comment. Best Regards,
Michael
Implementation
Subject: Re: AW: Minutes of OVMS+ teleconference
Date: Thu, 12 Nov 2015 15:30:06 +0100
From: Jose Borelli <borelli@mpia.de>
Dear All,
Finally we had the time to sit down together with Michael to implement the OPD estimation code. I just committed it into trunk and need to be
tested over there.
The changes in the protocol are the following:
The UEI status package, periodically sent to the clients, contains the OPD estimation mode and the number of double numbers that will follow
the standard channel information (depending of the mentioned mode).
By default, the racktangle uses mode -E 0, which means that there is no OPD calculation:
0= no estimation(default)
1= differential TT
2= differential TT + SX/DX TT
3= OPD TT for all mirros separately.
The data package looks like this:
TIME_STAMP, DEV_1-CH_1, ..., DEV_1-CH_4, ..., DEV_N-CH_4, OPD_EST_1,ODP_EST_N.
The status package looks like this:
status[0] = -1.0;
status[1] = numDevices;
status[2] = numChannels;
status[3] = frequency;
status[4] = gain;
status[5] = hpf;
status[6] = simulationFlag;
status[7] = currentICP;
status[8] = estimationMode;
status[9] = estimationSize;
The clients should calculate the size of each slice of data as follows:
TIME_STAMP (1) + (DEVS * CHANNELS) + OPD_ESTIMATION_SIZE
Hope this is clear enough.
Let us know when you have the chance to test it. Since we modified the
protocol, you should recompile and install everything on the ovms server.
I have updated the developer manual as well. Michael will do likewise
with the user manual.
Best regards,
Jose
Date: Tue, 17 Nov 2015 12:56:09 +0100
From: Böhm, Michael <michael.boehm@isys.uni-stuttgart.de>
To: Elwood Downey <edowney@lbti.org>
Hi Elwood,
Basically, the number of the additional channels depends on the estimationMode field. The estimationSize field actually gives you the number of channels (3, 5, or 18).
These are appended to the accelerometer values.
So what you get is the following:
Channel 0 1 2 \x85 n n+1 \x85 n+m
Data time acc_1 acc_2 \x85 acc_n est_1 \x85 est_m
Where m is equal to estimationSize and n is equal to numDevices*numChannels
, so you have to read these fields as well.
So the first estimated value would be buffer[numDevices*numChannels + 1]
and the last is buffer=[numDevices*numChannels + estimationSize]= .
So for the special case of a fully equipped RackTangle (12 cards, 4 channels) and estimation mode 1, those channels are indeed 50 \x96 52, accessed by buffer[49] to buffer[51].
For any other case this could be different, though, as explained above.
Was this helpful?
Let me know if there is any confusion left. I think the above is also explained in the updated developer manual.
Best Regards,
Michael
A configuration file named
config.txt
is used on the RackTangle to specify the accelerometer channels and locations to use for the calculations. Only accelerometers measuring along the optical axis are used to determine opd, tip and tilt for each mirror. The user specifies a) location b) channel c) calibration data for each of the accelerometers used.
For example,
M2_SX
has 3 accelerometers measuring along the optical axis located at:
x_1 = 0, y_1 = 0.8500
x_2 = -0.7361, y_2 = -0.4250
x_3 = 0.7987, y_3 = -0.4250
According to my documents, these are connected to the following channels (counting from 1 to 48):
c_1 = 2 (1-2)
c_2 = 4 (1-4)
c_3 = 3 (1-3)
These sensors have the following calibration gain (Michael didn't actually know these values, so set them to one. These calibration sheets should be around at LBTO):
k_1 = 1.0
k_2 = 1.0
k_3 = 1.0
So basically, for each sensor, there is one line in each section.
If LBTO ever decides to change the location of or add more sensors along the optical axis, then those can be added to the config file and improve the overall result.
Testing
Tested by comparing new telemetry to old telemetry to verify the data looks similar.
LBTI tested 17-November and successfully read the new (mode 1) 3 estimation values.
Telemetry
Created three streams to write for each estimation mode.
Stream |
Fields |
opd_estimation_mode1 |
opd, tip, tilt |
opd_estimation_mode2 |
opd, tip_sx, tilt_sx, tip_dx, tilt_dx |
opd_estimation_mode3 |
opd_m1_sx, opd_m2_sx, opd_m3_sx, opd_m1_dx, opd_m2_dx, opd_m3_dx, tip_m1_sx, tip_m2_sx, tip_m3_sx, tip_m1_dx, tip_m2_dx, tip_m3_dx, tilt_m1_sx, tilt_m2_sx, tilt_m3_sx, tilt_m1_dx, tilt_m2_dx, tilt_m3_dx |
- Found that the reason we cannot clear out the buffer when shutting down is because it is set up as diagnostic streams. Diagnostic streams hang on to the buffer contents and it gets dropped when the process goes away. Did some standalone testing of a diagnostic stream to understand what's going on. Basically, the
readBuf
counts down to 0, but the writeBuf
does not. This is what he calls the disk buffer. I cannot tell what we could do to make the diagnostic streams do a flush
- it's out there in the base class, but nothing calls it and we do not have access to the stream - we use the collector as our interface.
- It would be nice to not create the stream unless we're in the particular mode. I'll have to look at that, since we'll have to get a status packet before writing. Maybe it's not too bad. First cut at this creates all three streams on startup.
The streams are not created until the first call to resume
collection. And then it starts the WorkerThread
. We don't have a status packet until the WorkerThread
is going, reading packets.
Notes / Issues
- Need to add the estimation parameters to the monitor for graphing.