Skip to content

Commit 402bb9b

Browse files
fix(output): Fixing output filter implementation (#65)
1 parent 5a05810 commit 402bb9b

File tree

7 files changed

+221
-41
lines changed

7 files changed

+221
-41
lines changed

examples/data/program-test-6.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{ "title": "RSI",
2+
"description": "This program is generated by the compiler, it represents the bollinger bands operator",
3+
"date": "now",
4+
"apiVersion": "v1",
5+
"author": "Eduardo",
6+
"entryOperator": "754",
7+
"output": { "37": [ "o1", "o2" ] },
8+
"operators": [
9+
{ "id": "37", "type": "Output", "numPorts": 2 },
10+
{ "id": "495", "type": "Minus" },
11+
{ "id": "861", "type": "Plus" },
12+
{ "id": "996", "type": "Scale", "value": 2 },
13+
{ "id": "865", "type": "StandardDeviation", "n": 14 },
14+
{ "id": "510", "type": "MovingAverage", "n": 14 },
15+
{ "id": "262", "type": "HermiteResampler", "dt": 1 },
16+
{ "id": "754", "type": "Input", "numPorts": 1 }
17+
],
18+
"connections": [
19+
{ "from": "495", "to": "37", "fromPort": "o1", "toPort": "i2" },
20+
{ "from": "861", "to": "37", "fromPort": "o1", "toPort": "i1" },
21+
{ "from": "996", "to": "495", "fromPort": "o1", "toPort": "i2" },
22+
{ "from": "510", "to": "495", "fromPort": "o1", "toPort": "i1" },
23+
{ "from": "996", "to": "861", "fromPort": "o1", "toPort": "i2" },
24+
{ "from": "510", "to": "861", "fromPort": "o1", "toPort": "i1" },
25+
{ "from": "865", "to": "996", "fromPort": "o1", "toPort": "i1" },
26+
{ "from": "262", "to": "865", "fromPort": "o1", "toPort": "i1" },
27+
{ "from": "262", "to": "510", "fromPort": "o1", "toPort": "i1" },
28+
{ "from": "754", "to": "262", "fromPort": "o1", "toPort": "i1" }
29+
]
30+
}

libs/api/include/rtbot/Program.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct Program {
2222

2323
Program(Program const&) = delete;
2424
void operator=(Program const&) = delete;
25-
Program(Program&& other)=default;
25+
Program(Program&& other) = default;
2626

2727
string getProgramEntryOperatorId() { return entryOperator; }
2828

@@ -51,16 +51,20 @@ struct Program {
5151
if (outResults.count(op->second.at(i)) > 0) {
5252
map<string, vector<Message<uint64_t, double>>> opReturn;
5353
opReturn.emplace(op->second.at(i), outResults.at(op->second.at(i)));
54-
toReturn.emplace(op->first, opReturn);
54+
if (toReturn.count(op->first) == 0)
55+
toReturn.emplace(op->first, opReturn);
56+
else
57+
Operator<uint64_t, double>::mergeOutput(toReturn[op->first], opReturn);
5558
}
5659
}
5760
}
5861
}
5962

60-
if (this->outputFilter.empty())
63+
if (this->outputFilter.empty()) {
6164
return opResults;
62-
else
65+
} else {
6366
return toReturn;
67+
}
6468
}
6569

6670
/// return a list of the operator that emitted: id, output message

libs/api/test/BUILD.bazel

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ cc_test(
1616
"//examples/data:program-test-2.json",
1717
"//examples/data:program-test-3.json",
1818
"//examples/data:program-test-4.json",
19-
"//examples/data:program-test-5.json"
19+
"//examples/data:program-test-5.json",
20+
"//examples/data:program-test-6.json"
2021
],
2122
# defines = ["CATCH_CONFIG_MAIN"],
2223
deps = [
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#include <catch2/catch.hpp>
2+
#include <fstream>
3+
#include <iostream>
4+
#include <nlohmann/json.hpp>
5+
6+
#include "rtbot/FactoryOp.h"
7+
#include "rtbot/bindings.h"
8+
#include "tools.h"
9+
10+
using namespace rtbot;
11+
using namespace std;
12+
13+
TEST_CASE("read pipeline test bollinger_bands") {
14+
nlohmann::json json;
15+
{
16+
ifstream in("examples/data/program-test-6.json");
17+
if (!in) throw runtime_error("file not found");
18+
in >> json;
19+
}
20+
21+
SECTION("test generated bollinger_bands") {
22+
auto pipe = FactoryOp::createProgram(json.dump().c_str());
23+
24+
srand(time(nullptr));
25+
vector<int> v;
26+
int start = 0;
27+
int end = 10000;
28+
int o1 = 0;
29+
int o2 = 0;
30+
int lastdown = -1;
31+
int lastup = -1;
32+
v.push_back(start);
33+
for (int i = start + 1; i < end; i++) {
34+
int random_value = rand();
35+
if (random_value < (RAND_MAX / 2)) {
36+
v.push_back(i);
37+
}
38+
}
39+
v.push_back(end);
40+
41+
for (int i = 0; i < v.size(); i++) {
42+
map<string, vector<Message<uint64_t, double>>> messagesMap;
43+
vector<Message<uint64_t, double>> x;
44+
x.push_back(Message<uint64_t, double>(v.at(i), v.at(i) * v.at(i)));
45+
messagesMap.emplace("i1", x);
46+
47+
auto output = pipe.receive(messagesMap);
48+
49+
if (output.count("37") > 0) {
50+
if (output.find("37")->second.count("o1") > 0) {
51+
for (int j = 0; j < output.find("37")->second.find("o1")->second.size(); j++) {
52+
int now = output.find("37")->second.find("o1")->second.at(j).time;
53+
if (lastup >= 0) REQUIRE(now - 1 == lastup);
54+
lastup = now;
55+
o1++;
56+
}
57+
}
58+
if (output.find("37")->second.count("o2") > 0) {
59+
for (int j = 0; j < output.find("37")->second.find("o2")->second.size(); j++) {
60+
int now = output.find("37")->second.find("o2")->second.at(j).time;
61+
if (lastdown >= 0) REQUIRE(now - 1 == lastdown);
62+
lastdown = now;
63+
o2++;
64+
}
65+
}
66+
}
67+
}
68+
REQUIRE(o1 == o2);
69+
}
70+
}

libs/std/include/rtbot/std/CosineResampler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ struct CosineResampler : public Operator<T, V> {
6868
*/
6969
static V cosineInterpolate(V y1, V y2, V mu) {
7070
V mu2;
71-
mu2 = (1 - cos(mu * 3.141592653589)) / 2;
71+
mu2 = (1 - cos(mu * 3.1415926535897932)) / 2;
7272
return (y1 * (1 - mu2) + y2 * mu2);
7373
}
7474
};
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include <catch2/catch.hpp>
2+
3+
#include "rtbot/std/CosineResampler.h"
4+
5+
using namespace rtbot;
6+
using namespace std;
7+
8+
TEST_CASE("Cosine Resampler test emit at right frequencies") {
9+
auto i1 = CosineResampler<uint64_t, double>("i1", 99);
10+
auto i2 = CosineResampler<uint64_t, double>("i2", 99);
11+
auto i3 = CosineResampler<uint64_t, double>("i3", 1);
12+
13+
SECTION("emits once") {
14+
for (int i = 0; i < 20; i++) {
15+
i1.receiveData(Message<uint64_t, double>(i * 100, i * i));
16+
map<string, map<string, vector<Message<uint64_t, double>>>> emitted = i1.executeData();
17+
18+
if (i == 0)
19+
REQUIRE(emitted.empty());
20+
else {
21+
REQUIRE(emitted.find("i1")->second.find("o1")->second.at(0).time == 99 * i);
22+
}
23+
}
24+
}
25+
26+
SECTION("emits twice") {
27+
for (int i = 0; i < 20; i++) {
28+
i2.receiveData(Message<uint64_t, double>(i * 200, i * i));
29+
map<string, map<string, vector<Message<uint64_t, double>>>> emitted = i2.executeData();
30+
31+
if (i == 0)
32+
REQUIRE(emitted.empty());
33+
else {
34+
REQUIRE(emitted.find("i2")->second.find("o1")->second.at(0).time == 99 * (2 * i - 1));
35+
REQUIRE(emitted.find("i2")->second.find("o1")->second.at(1).time == 99 * (2 * i));
36+
}
37+
}
38+
}
39+
40+
SECTION("emits every time, one next to the next one") {
41+
srand(time(nullptr));
42+
vector<int> v;
43+
int start = 0;
44+
int end = 2000;
45+
int last = start;
46+
v.push_back(start);
47+
for (int i = start + 1; i < end; i++) {
48+
int random_value = rand();
49+
if (random_value < (RAND_MAX / 2)) {
50+
v.push_back(i);
51+
}
52+
}
53+
v.push_back(end);
54+
55+
for (int i = 0; i < v.size(); i++) {
56+
i3.receiveData(Message<uint64_t, double>(v.at(i), v.at(i) * v.at(i)));
57+
map<string, map<string, vector<Message<uint64_t, double>>>> emitted = i3.executeData();
58+
59+
if (i == 0) {
60+
// cout << "******* (" << v.at(i) << ") *******" << endl;
61+
REQUIRE(emitted.empty());
62+
} else {
63+
// cout << "******* (" << v.at(i) << ") *******" << endl;
64+
for (int j = 0; j < emitted.find("i3")->second.find("o1")->second.size(); j++) {
65+
int now = emitted.find("i3")->second.find("o1")->second.at(j).time;
66+
REQUIRE(now - 1 == last);
67+
last = now;
68+
// cout << now << endl;
69+
}
70+
}
71+
}
72+
}
73+
}
Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,15 @@
11
#include <catch2/catch.hpp>
22

3-
#include "rtbot/std/CosineResampler.h"
43
#include "rtbot/std/HermiteResampler.h"
54

65
using namespace rtbot;
76
using namespace std;
87

9-
TEST_CASE("Cosine Resampler test emit at right frequencies") {
10-
auto i1 = CosineResampler<uint64_t, double>("i1", 99);
11-
auto i2 = CosineResampler<uint64_t, double>("i2", 99);
12-
13-
SECTION("emits once") {
14-
for (int i = 0; i < 20; i++) {
15-
i1.receiveData(Message<uint64_t, double>(i * 100, i * i));
16-
map<string, map<string, vector<Message<uint64_t, double>>>> emitted = i1.executeData();
17-
18-
if (i == 0)
19-
REQUIRE(emitted.empty());
20-
else {
21-
REQUIRE(emitted.find("i1")->second.find("o1")->second.at(0).time == 99 * i);
22-
}
23-
}
24-
}
25-
26-
SECTION("emits twice") {
27-
for (int i = 0; i < 20; i++) {
28-
i2.receiveData(Message<uint64_t, double>(i * 200, i * i));
29-
map<string, map<string, vector<Message<uint64_t, double>>>> emitted = i2.executeData();
30-
31-
if (i == 0)
32-
REQUIRE(emitted.empty());
33-
else {
34-
REQUIRE(emitted.find("i2")->second.find("o1")->second.at(0).time == 99 * (2 * i - 1));
35-
REQUIRE(emitted.find("i2")->second.find("o1")->second.at(1).time == 99 * (2 * i));
36-
}
37-
}
38-
}
39-
}
40-
418
TEST_CASE("Hermite Resampler test emit at right frequencies") {
429
auto i1 = HermiteResampler<uint64_t, double>("i1", 99);
4310
auto i2 = HermiteResampler<uint64_t, double>("i2", 99);
4411
auto i3 = HermiteResampler<int64_t, double>("i3", 99);
12+
auto i4 = HermiteResampler<int64_t, double>("i4", 1);
4513

4614
SECTION("emits once") {
4715
for (int i = 0; i < 20; i++) {
@@ -80,8 +48,8 @@ TEST_CASE("Hermite Resampler test emit at right frequencies") {
8048

8149
SECTION("emits right values") {
8250
for (int i = 0; i < 20; i++) {
83-
i3.receiveData(Message<std::int64_t, double>(i * 100, i * i));
84-
map<string, map<string, vector<Message<std::int64_t, double>>>> emitted = i3.executeData();
51+
i3.receiveData(Message<int64_t, double>(i * 100, i * i));
52+
map<string, map<string, vector<Message<int64_t, double>>>> emitted = i3.executeData();
8553

8654
if (i == 0 || i == 1 || i == 2)
8755
REQUIRE(emitted.empty());
@@ -94,4 +62,38 @@ TEST_CASE("Hermite Resampler test emit at right frequencies") {
9462
}
9563
}
9664
}
65+
66+
SECTION("emits every time, one next to the next one") {
67+
srand(time(nullptr));
68+
vector<int> v;
69+
int start = 0;
70+
int end = 2000;
71+
int last = start;
72+
v.push_back(start);
73+
for (int i = start + 1; i < end; i++) {
74+
int random_value = rand();
75+
if (random_value < (RAND_MAX / 2)) {
76+
v.push_back(i);
77+
}
78+
}
79+
v.push_back(end);
80+
81+
for (int i = 0; i < v.size(); i++) {
82+
i4.receiveData(Message<int64_t, double>(v.at(i), v.at(i) * v.at(i)));
83+
map<string, map<string, vector<Message<int64_t, double>>>> emitted = i4.executeData();
84+
85+
if (i == 0 || i == 1 || i == 2) {
86+
// cout << "******* (" << v.at(i) << ") *******" << endl;
87+
REQUIRE(emitted.empty());
88+
} else {
89+
// cout << "******* (" << v.at(i) << ") *******" << endl;
90+
for (int j = 0; j < emitted.find("i4")->second.find("o1")->second.size(); j++) {
91+
int now = emitted.find("i4")->second.find("o1")->second.at(j).time;
92+
REQUIRE(now - 1 == last);
93+
last = now;
94+
// cout << now << endl;
95+
}
96+
}
97+
}
98+
}
9799
}

0 commit comments

Comments
 (0)