15:18, EET
December 20, 2016
Hi,
we currently have the problem, that we historize two nodes (of type double array). The function to set a value is always called for every node, so there should be exactly the same nr. of history variables. But there isn’t. Is there some internal function that checks if the value has changed since the last time and only then adds a history record? How does this function look? Is there some epsion value for doubles?
Thanks,
lg Manu
15:43, EET
December 21, 2011
The SDK does not define any history storage. The only history storage is provided as part of the SampleConsoleServer. It is only provided as an example of a very basic history storage.
So, if you have copied your implementation from the example, you can also verify it directly how it works and modify it according to your needs.
UaVariableNode (or CacheVariable) filters the changes, if you change the value of the variable. It only provides DataChange notifications, when the value actually changes. there is no epsilon.
14:52, EET
December 20, 2016
11:58, EET
December 21, 2011
The plain change of ServerTimestamp will not trigger any change from the UaVariableNode. But if the SourceTimestamp changes, you do get a data change from the variable.
However, I was not quite sure what you want to accomplish. Typically you only need the changes in the history and you can assume values haven’t changed after that (in stepped mode). If you want to interpolate values between the changes, then it would make sense to store the in-between values even when they haven’t changed. But I would trust the SourceTimestamp in this case as well.
15:31, EET
December 20, 2016
We use the codegenerator. How can we force a reset of the sourceTimestamp there?
The idea is to have several values collected at a fixed sampling rate. E.g. 30ms. If one value doesn’t change in some timespan, we nevertheless want a datapoint because elseway the time-dimension is not constant between different collected values.
12:06, EET
December 21, 2011
12:23, EET
April 3, 2012
Hmm I looked this now and it actually seems to be a bug.
The setValue accepts raw values, Variants and DataValues, and in the case of the 2 first ones it does not set the sourcetimestamp correctly if the value is equal to previous one.
As a workaround until next release you could use the setValue by providing complete DataValue for which you can set the timestamps.
i.e. for generated nodes XXXTypeNode.getYYYNode().setValue(DataValue)
– Bjarne
16:55, EET
December 20, 2016
Hi and thanks for your answer!
I can’t confirm this. I did now try the following, but I still don’t get the same nr. of values:
Variant myVariant = new Variant(value);
DataValue myDataValue = new DataValue();
myDataValue.setValue(myVariant);
myDataValue.setStatusCode(StatusCode.GOOD);
myDataValue.setServerTimestamp(DateTime.currentTime());
myDataValue.setSourceTimestamp(DateTime.currentTime());
node.setValue(myDataValue);
lg Manu
11:22, EET
December 20, 2016
14:26, EET
April 3, 2012
16:15, EET
December 20, 2016
Hi Bjarne,
sure:
private final ScheduledExecutorService simulator = Executors
.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());
simulator.scheduleAtFixedRate(this, 0, 25, TimeUnit.MILLISECONDS);
in the run() method, which is called every 25 milliseconds:
updateAxisAngles();
updateTorques();
The method looks like:
public void setAllAxisAngle(JointPosition axis) throws StatusException {
Axis axis = AddressSpace.getAxisNode();
// Be careful not getting an out of bounds error
ArrayList newValues = new ArrayList();
for (int i = 0; i < axis.getAxisCount(); i++)
newValues.add(axis.get(i));
Double[] newValuesAr = new Double[newValues.size()];
axis.setValues(newValues.toArray(newValuesAr));
}
updateTorques works the same
and axis.setValues is generated by the jave codegenerator. I tried to change the implementation as explained in the last post, but without success. In the end i get a different number of axis and torques…
Thanks,
lg manu
16:50, EET
April 3, 2012
Ok that explains how you set the values. How are you observing them?
Can show the place/how “In the end i get a different number of axis and torques…”
Can you show the code where ” … so there should be exactly the same nr. of history variables.” i.e. I would need steps to reproduce this.
Mentioning this just in case.. based on the words you are using I would assume you are talking about the server side. If you are reading these from the client side, then of course this can happen as based on the code above you update axis first and then torgues.
9:57, EET
December 20, 2016
Hi,
ok on client side I use python-opcua. And i do a
for node in nodes_to_watch:
node_history = node.read_raw_history(starttime=starttime, endtime=endtime)
Start and endtime do not change. And finally I get a different number of history elements for the two nodes. I would agree with you, if this would just be a difference of one, then maybe we were reading exactly between writing the one and the other node on server side. But when recording longer time, the numbers diverge by 200 or so.
lg
10:39, EET
April 3, 2012
Just to be clear, how are you recording and storing the history data and returning it to the client (i.e. what are you doing onReadRaw call if you implemented HistoryManagerListener or readRaw if you are extending HistoryManager instead)?
And to understand you application needs better: what are the requirements for the history data, i.e. must it survive a restart of the server?
11:05, EEST
December 20, 2016
Hi Bjarne,
The requirements for the history data:
– It must not survive a restart
– We have to collect data from a device at a fix time interval e.g. 25ms. For every timestep several nodes are written. E.g. one node (an array of 7 axis values) another node an array of (6 force values).
The code is mainly from the example server. So at the history manager listener there is for onReadRaw:
ValueHistory history = variableHistories.get(node);
if (history != null) {
List values = new ArrayList();
int firstIndex = continuationPoint == null ? 0 : (Integer) continuationPoint;
Integer newContinuationPoint = history.readRaw(startTime, endTime, numValuesPerNode.intValue(),
returnBounds, firstIndex, values);
historyData.setDataValues(values.toArray(new DataValue[values.size()]));
return newContinuationPoint;
}
return null;
In ValueHistory we have:
public Integer readRaw(DateTime startTime, DateTime endTime, int maxValues, boolean returnBounds, int firstIndex,
List history) {
int i = 0;
boolean startTimeDefined = startTime.compareTo(DateTime.MIN_VALUE) > 0;
boolean endTimeDefined = endTime.compareTo(DateTime.MIN_VALUE) > 0;
if (startTimeDefined || !endTimeDefined)
for (DataValue value : values) {
DateTime t = value.getSourceTimestamp();
if (t == null)
t = value.getServerTimestamp();
final int compareToEnd = endTimeDefined ? t.compareTo(endTime) : -1;
if ((compareToEnd > 0) || (!returnBounds && (compareToEnd == 0)))
break;
else {
final int compareToStart = t.compareTo(startTime);
if ((compareToStart > 0) || (returnBounds && (compareToStart == 0))) {
if (i >= firstIndex)
history.add(value);
i++;
if (history.size() == maxValues)
return i;
}
}
}
else
for (int j = values.size() – 1; j >= 0; j–) {
DataValue value = values.get(j);
DateTime t = value.getSourceTimestamp();
if (t == null)
t = value.getServerTimestamp();
final int compareToEnd = t.compareTo(endTime);
if ((compareToEnd > 0) || (!returnBounds && (compareToEnd == 0)))
continue;
else {
if (i >= firstIndex)
history.add(value);
i++;
if (history.size() == maxValues)
return i;
}
}
return null;
}
and readAtTimes() is:
public DataValue[] readAtTimes(DateTime[] reqTimes) {
if (reqTimes == null)
return null;
DataValue[] values = new DataValue[reqTimes.length];
for (int i = 0; i < reqTimes.length; i++) {
DateTime t = reqTimes[i];
// Stepped interpolation used to get values
DataValue v = getValue(t);
values[i] = new DataValue(v == null ? null : v.getValue(),
v == null ? new StatusCode(StatusCodes.Bad_NoData) : v.getStatusCode(), t, UnsignedShort.ZERO, null,
null);
}
return values;
}
Most Users Ever Online: 1919
Currently Online:
30 Guest(s)
Currently Browsing this Page:
1 Guest(s)
Top Posters:
Heikki Tahvanainen: 402
hbrackel: 144
rocket science: 88
pramanj: 86
Francesco Zambon: 83
Ibrahim: 78
Sabari: 62
kapsl: 57
gjevremovic: 49
Xavier: 43
Member Stats:
Guest Posters: 0
Members: 730
Moderators: 7
Admins: 1
Forum Stats:
Groups: 3
Forums: 15
Topics: 1529
Posts: 6471
Newest Members:
HypromeImpupe, toneylapham544, rondawolinski7, Marypof5711, roycedelargie91, kourtneyquisenbe, ellis87832073466, zkxwilliemae, gabriellabachus, DeakinModerators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1032, Jimmy Ni: 26, Matti Siponen: 349, Lusetti: 0
Administrators: admin: 1