Statistics
| Branch: | Tag: | Revision:

humotion / src / timestamped_list.cpp @ d21cdd06

History | View | Annotate | Download (6.186 KB)

1 8c6c1163 Simon Schulz
/*
2
* This file is part of humotion
3
*
4
* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
5
* http://opensource.cit-ec.de/projects/humotion
6
*
7
* This file may be licensed under the terms of the
8
* GNU Lesser General Public License Version 3 (the ``LGPL''),
9
* or (at your option) any later version.
10
*
11
* Software distributed under the License is distributed
12
* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
13
* express or implied. See the LGPL for the specific language
14
* governing rights and limitations.
15
*
16
* You should have received a copy of the LGPL along with this
17
* program. If not, go to http://www.gnu.org/licenses/lgpl.html
18
* or write to the Free Software Foundation, Inc.,
19
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
*
21
* The development of this software was supported by the
22
* Excellence Cluster EXC 277 Cognitive Interaction Technology.
23
* The Excellence Cluster EXC 277 is a grant of the Deutsche
24
* Forschungsgemeinschaft (DFG) in the context of the German
25
* Excellence Initiative.
26
*/
27
28
#include "timestamped_list.h"
29
#include "assert.h"
30
31
using namespace std;
32
using namespace boost;
33
using namespace humotion;
34
35
TimestampedList::TimestampedList(unsigned int s){
36 7ed40bef Simon Schulz
    //initialize the list to its desired size:
37 8c6c1163 Simon Schulz
    TimestampedFloat now;
38
    tsf_list.resize(s, now);
39
}
40
41
TimestampedList::TimestampedList(TimestampedList const &l){
42
    //lock the tsf_list for this access. by doing this we assure
43
    //that no other thread accessing this element can diturb the
44
    //following atomic instructions:
45
    mutex::scoped_lock scoped_lock(l.access_mutex);
46
47
    //now do a deep copy with locking!
48
    tsf_list = l.tsf_list;
49
}
50
51
void TimestampedList::copy_tsf_list_to(timestamped_float_list_t *target){
52
    //lock the tsf_list for this access. by doing this we assure
53
    //that no other thread accessing this element can diturb the
54
    //following atomic instructions:
55
    mutex::scoped_lock scoped_lock(access_mutex);
56
57
    *target = tsf_list;
58
}
59
60 32327f15 Simon Schulz
Timestamp TimestampedList::get_last_timestamp(){
61 8c6c1163 Simon Schulz
    //lock the tsf_list for this access. by doing this we assure
62
    //that no other thread accessing this element can diturb the
63
    //following atomic instructions:
64
    mutex::scoped_lock scoped_lock(access_mutex);
65
66
    if (tsf_list.empty()){
67 32327f15 Simon Schulz
        return Timestamp(0,0);
68 8c6c1163 Simon Schulz
    }
69
70
    timestamped_float_list_t::iterator it = tsf_list.end();
71
    it--;
72
    return it->timestamp;
73
}
74
75 32327f15 Simon Schulz
void TimestampedList::insert(Timestamp timestamp, float val){
76 7ed40bef Simon Schulz
    //erase first element:
77 8c6c1163 Simon Schulz
    tsf_list.pop_front();
78
    tsf_list.push_back(TimestampedFloat(timestamp, val));
79
    //printf("insert [%5.3f] = %5.1f\n",timestamp,val);
80
}
81
82
float TimestampedList::get_newest_value(){
83
    //lock the tsf_list for this access. by doing this we assure
84
    //that no other thread accessing this element can diturb the
85
    //following atomic instructions:
86
    mutex::scoped_lock scoped_lock(access_mutex);
87
88
    if (tsf_list.empty()){
89 32327f15 Simon Schulz
        printf("> WARNING: requested newest value from empty list, returning 0.0\n");
90 8c6c1163 Simon Schulz
        return 0.0;
91
    }
92
93
    timestamped_float_list_t::iterator it = tsf_list.end();
94 7ed40bef Simon Schulz
    it--;
95
    return it->value;
96 8c6c1163 Simon Schulz
}
97
98 32327f15 Simon Schulz
float TimestampedList::get_interpolated_value(Timestamp target_ts){
99 8c6c1163 Simon Schulz
    //lock the tsf_list for this access. by doing this we assure
100
    //that no other thread accessing this element can diturb the
101
    //following atomic instructions:
102
    mutex::scoped_lock scoped_lock(access_mutex);
103
104
    ///target_ts -= 0.001 * 4;
105 7ed40bef Simon Schulz
106 8c6c1163 Simon Schulz
    TimestampedFloat previous;
107 32327f15 Simon Schulz
    //printf("> latency %3.2fms\n", (Timestamped().to_seconds() - target_ts.to_seconds())*1000.0);
108 8c6c1163 Simon Schulz
109
    for ( timestamped_float_list_t::iterator it = tsf_list.begin(); it != tsf_list.end(); ++it ){
110 7ed40bef Simon Schulz
        if (it->timestamp >= target_ts){
111
            //ok found close target
112 8c6c1163 Simon Schulz
            if (it == tsf_list.begin()){
113 7ed40bef Simon Schulz
                //no preceding element
114 32327f15 Simon Schulz
                printf("> warning, timestamp %6.3f smaller than first element %6.3f in timestamped list. this should not happen (increase ts buffer?)\n",target_ts.to_seconds(),tsf_list.begin()->timestamp.to_seconds());
115 7ed40bef Simon Schulz
                return it->value;
116
            }else{
117
                //do interpolation
118
                return interpolate(*it, previous, target_ts);
119
            }
120
        }
121
        previous = *it;
122
    }
123
124
    //we reached the end, return the last value
125 32327f15 Simon Schulz
    printf("> warning: found no timestamp bigger than %f in timestamped list...\n", target_ts.to_seconds());
126 7ed40bef Simon Schulz
    printf("           this should not happen as images will always be behind\n");
127 32327f15 Simon Schulz
    printf("           the motor data. returning most recent value (ts=%f)\n", previous.timestamp.to_seconds());
128 7ed40bef Simon Schulz
129
    return previous.value;
130 8c6c1163 Simon Schulz
}
131
132 32327f15 Simon Schulz
float TimestampedList::interpolate(TimestampedFloat a, TimestampedFloat b, Timestamp timestamp){
133 7ed40bef Simon Schulz
    //a->timestamp < timestamp <= b->timestamp
134 32327f15 Simon Schulz
    double dist_a = timestamp.to_seconds() - a.timestamp.to_seconds();
135
    double dist_b = b.timestamp.to_seconds() - timestamp.to_seconds();
136 7ed40bef Simon Schulz
    double dist   = dist_a + dist_b;
137
138 8c6c1163 Simon Schulz
    float interpolation = a.value + (dist_a / dist) * (b.value - a.value);
139 7ed40bef Simon Schulz
    return interpolation;
140 8c6c1163 Simon Schulz
}
141
142
143
///tests
144
void TimestampedList::run_tests(){
145 7ed40bef Simon Schulz
    int size = 10;
146
    TimestampedList list(size);
147
148
    for(int i=0; i<size; i++){
149 32327f15 Simon Schulz
        list.insert(Timestamp(i * 100.0,0), i*10.0);
150 7ed40bef Simon Schulz
    }
151
152
    //test algorithm:
153
154
    //test exact match:
155
    for(int i=0; i<size; i++){
156 32327f15 Simon Schulz
        Timestamp ts(i*100.0,0);
157
        printf("> testing get_interpolated_value(%f) == %f (value read back = %f)\n",ts.to_seconds(), i*10.0, list.get_interpolated_value(ts));
158
        assert( list.get_interpolated_value(ts) == i*10.0);
159 7ed40bef Simon Schulz
    }
160
    printf("passed test 1\n");
161
162 32327f15 Simon Schulz
    assert(list.get_interpolated_value(Timestamp(0.0,0)) == 0.0);
163
    assert(list.get_interpolated_value(Timestamp(110.0,0)) == 11.0);
164
    assert(list.get_interpolated_value(Timestamp(150.0,0)) == 15.0);
165
    assert(list.get_interpolated_value(Timestamp(999990.0,0)) == 90.0);
166 7ed40bef Simon Schulz
167
    printf("passed test 2\n");
168
169 32327f15 Simon Schulz
    list.insert(Timestamp(1000.0 ,0), 200.0);
170
    list.insert(Timestamp(1300.0, 0), -100.0);
171
    assert(list.get_interpolated_value(Timestamp(1100, 0)) == 100.0);
172
    assert(list.get_interpolated_value(Timestamp(1200, 0)) == 0.0);
173
    assert(list.get_interpolated_value(Timestamp(1300, 0)) == -100.0);
174
    assert(list.get_interpolated_value(Timestamp(1250, 0)) == -50.0);
175 7ed40bef Simon Schulz
176
    printf("passed test 3\n");
177
    exit(0);
178 8c6c1163 Simon Schulz
}