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.


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,



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:

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,


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,


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.


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.


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.
Topic revision: r6 - 16 Oct 2018, PetrKubanek
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback