Statistics
| Branch: | Tag: | Revision:

humotion / src / timestamped_list.cpp @ 8d293778

History | View | Annotate | Download (6.907 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 0c8d22a5 sschulz
#include <assert.h>
29 8c6c1163 Simon Schulz
30 0c8d22a5 sschulz
#include "humotion/timestamped_list.h"
31 8c6c1163 Simon Schulz
32 0c8d22a5 sschulz
using boost::mutex;
33
using humotion::TimestampedList;
34
35
TimestampedList::TimestampedList(unsigned int s) {
36
    // initialize the list to its desired size:
37 dbf66483 Florian Lier
    TimestampedFloat now(Timestamp::now(), 0.0);
38 ea068cf1 sschulz
    tsf_list_.resize(s, now);
39 8c6c1163 Simon Schulz
}
40
41 0c8d22a5 sschulz
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 ea068cf1 sschulz
    mutex::scoped_lock scoped_lock(l.access_mutex_);
46 8c6c1163 Simon Schulz
47 0c8d22a5 sschulz
    // now do a deep copy with locking!
48 ea068cf1 sschulz
    tsf_list_ = l.tsf_list_;
49 8c6c1163 Simon Schulz
}
50
51 0c8d22a5 sschulz
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 ea068cf1 sschulz
    mutex::scoped_lock scoped_lock(access_mutex_);
56 8c6c1163 Simon Schulz
57 ea068cf1 sschulz
    *target = tsf_list_;
58 8c6c1163 Simon Schulz
}
59
60 caf7373f Simon Schulz
61 0c8d22a5 sschulz
humotion::Timestamp TimestampedList::get_first_timestamp() {
62
    // lock the tsf_list for this access. by doing this we assure
63
    // that no other thread accessing this element can diturb the
64
    // following atomic instructions:
65 ea068cf1 sschulz
    mutex::scoped_lock scoped_lock(access_mutex_);
66 caf7373f Simon Schulz
67 ea068cf1 sschulz
    if (tsf_list_.empty()) {
68 0c8d22a5 sschulz
        return Timestamp(0, 0);
69 caf7373f Simon Schulz
    }
70
71 ea068cf1 sschulz
    timestamped_float_list_t::iterator it = tsf_list_.begin();
72 caf7373f Simon Schulz
    return it->timestamp;
73
}
74
75 0c8d22a5 sschulz
humotion::Timestamp TimestampedList::get_last_timestamp() {
76
    // lock the tsf_list for this access. by doing this we assure
77
    // that no other thread accessing this element can diturb the
78
    // following atomic instructions:
79 ea068cf1 sschulz
    mutex::scoped_lock scoped_lock(access_mutex_);
80 8c6c1163 Simon Schulz
81 ea068cf1 sschulz
    if (tsf_list_.empty()) {
82 0c8d22a5 sschulz
        return Timestamp(0, 0);
83 8c6c1163 Simon Schulz
    }
84
85 ea068cf1 sschulz
    timestamped_float_list_t::iterator it = tsf_list_.end();
86 8c6c1163 Simon Schulz
    it--;
87
    return it->timestamp;
88
}
89
90 0c8d22a5 sschulz
void TimestampedList::insert(Timestamp timestamp, float val) {
91
    // erase first element:
92 ea068cf1 sschulz
    tsf_list_.pop_front();
93
    tsf_list_.push_back(TimestampedFloat(timestamp, val));
94 0c8d22a5 sschulz
    // printf("insert [%5.3f] = %5.1f\n",timestamp,val);
95 8c6c1163 Simon Schulz
}
96
97 0c8d22a5 sschulz
float TimestampedList::get_newest_value() {
98
    // lock the tsf_list for this access. by doing this we assure
99
    // that no other thread accessing this element can diturb the
100
    // following atomic instructions:
101 ea068cf1 sschulz
    mutex::scoped_lock scoped_lock(access_mutex_);
102 8c6c1163 Simon Schulz
103 ea068cf1 sschulz
    if (tsf_list_.empty()) {
104 32327f15 Simon Schulz
        printf("> WARNING: requested newest value from empty list, returning 0.0\n");
105 8c6c1163 Simon Schulz
        return 0.0;
106
    }
107
108 ea068cf1 sschulz
    timestamped_float_list_t::iterator it = tsf_list_.end();
109 7ed40bef Simon Schulz
    it--;
110
    return it->value;
111 8c6c1163 Simon Schulz
}
112
113 0c8d22a5 sschulz
float TimestampedList::get_interpolated_value(Timestamp target_ts) {
114
    // lock the tsf_list for this access. by doing this we assure
115
    // that no other thread accessing this element can diturb the
116
    // following atomic instructions:
117 ea068cf1 sschulz
    mutex::scoped_lock scoped_lock(access_mutex_);
118 8c6c1163 Simon Schulz
119
    TimestampedFloat previous;
120 0c8d22a5 sschulz
    // printf("> latency %3.2fms\n", (Timestamped().to_seconds() - target_ts.to_seconds())*1000.0);
121
122 ea068cf1 sschulz
    for ( timestamped_float_list_t::iterator it = tsf_list_.begin(); it != tsf_list_.end(); ++it ) {
123 5cd4364c sschulz
        if (it->timestamp == target_ts) {
124
            // perfect match, return this value
125
            return it->value;
126
        } else if (it->timestamp > target_ts) {
127 0c8d22a5 sschulz
            // ok found close target
128 ea068cf1 sschulz
            if (it == tsf_list_.begin()) {
129 0c8d22a5 sschulz
                // no preceding element
130
                printf("> warning, timestamp %6.3f smaller than first element %6.3f in timestamped"
131
                       "list. this should not happen (increase ts buffer?)\n",
132 ea068cf1 sschulz
                       target_ts.to_seconds(), tsf_list_.begin()->timestamp.to_seconds());
133 7ed40bef Simon Schulz
                return it->value;
134 0c8d22a5 sschulz
            } else {
135
                // do interpolation
136 7ed40bef Simon Schulz
                return interpolate(*it, previous, target_ts);
137
            }
138
        }
139
        previous = *it;
140
    }
141
142 0c8d22a5 sschulz
    // we reached the end, return the last value
143
    printf("> warning: found no timestamp >= than %f in timestamped list...\n",
144
           target_ts.to_seconds());
145 7ed40bef Simon Schulz
    printf("           this should not happen as images will always be behind\n");
146 0c8d22a5 sschulz
    printf("           the motor data. returning most recent value (ts=%f)\n",
147
           previous.timestamp.to_seconds());
148 7ed40bef Simon Schulz
149
    return previous.value;
150 8c6c1163 Simon Schulz
}
151
152 0c8d22a5 sschulz
float TimestampedList::interpolate(TimestampedFloat a, TimestampedFloat b, Timestamp timestamp) {
153
    // a->timestamp < timestamp <= b->timestamp
154 32327f15 Simon Schulz
    double dist_a = timestamp.to_seconds() - a.timestamp.to_seconds();
155
    double dist_b = b.timestamp.to_seconds() - timestamp.to_seconds();
156 7ed40bef Simon Schulz
    double dist   = dist_a + dist_b;
157
158 8c6c1163 Simon Schulz
    float interpolation = a.value + (dist_a / dist) * (b.value - a.value);
159 7ed40bef Simon Schulz
    return interpolation;
160 8c6c1163 Simon Schulz
}
161
162
163 0c8d22a5 sschulz
// tests
164
void TimestampedList::run_tests() {
165 7ed40bef Simon Schulz
    int size = 10;
166
    TimestampedList list(size);
167
168 0c8d22a5 sschulz
    for (int i = 0; i < size; i++) {
169
        list.insert(Timestamp(i * 100.0, 0), i*10.0);
170 7ed40bef Simon Schulz
    }
171
172 0c8d22a5 sschulz
    // test algorithm:
173 7ed40bef Simon Schulz
174 0c8d22a5 sschulz
    // test exact match:
175
    for (int i =0 ; i < size; i++) {
176
        Timestamp ts(i*100.0, 0);
177
        printf("> testing get_interpolated_value(%f) == %f (value read back = %f)\n",
178
               ts.to_seconds(), i*10.0, list.get_interpolated_value(ts));
179
        assert(list.get_interpolated_value(ts) == i*10.0);
180 7ed40bef Simon Schulz
    }
181
    printf("passed test 1\n");
182
183 0c8d22a5 sschulz
    assert(list.get_interpolated_value(Timestamp(0.0, 0)) == 0.0);
184
    assert(list.get_interpolated_value(Timestamp(110.0, 0)) == 11.0);
185
    assert(list.get_interpolated_value(Timestamp(150.0, 0)) == 15.0);
186
    assert(list.get_interpolated_value(Timestamp(999990.0, 0)) == 90.0);
187 7ed40bef Simon Schulz
188
    printf("passed test 2\n");
189
190 0c8d22a5 sschulz
    list.insert(Timestamp(1000.0, 0), 200.0);
191 32327f15 Simon Schulz
    list.insert(Timestamp(1300.0, 0), -100.0);
192
    assert(list.get_interpolated_value(Timestamp(1100, 0)) == 100.0);
193
    assert(list.get_interpolated_value(Timestamp(1200, 0)) == 0.0);
194
    assert(list.get_interpolated_value(Timestamp(1300, 0)) == -100.0);
195
    assert(list.get_interpolated_value(Timestamp(1250, 0)) == -50.0);
196 7ed40bef Simon Schulz
197
    printf("passed test 3\n");
198 0c8d22a5 sschulz
    exit(EXIT_SUCCESS);
199 8c6c1163 Simon Schulz
}