dragonpilot beta3

date: 2024-07-13T18:45:35
commit: c25d768a9e
This commit is contained in:
dragonpilot
2024-07-13 18:44:15 +08:00
committed by Comma Device
parent 0094c9ac06
commit cbd22eca29
228 changed files with 13037 additions and 2770 deletions
View File
+8
View File
@@ -1,6 +1,14 @@
dragonpilot 0.9.8
=======================
* Up to comma.ai openpilot master branch commit 01c2174d5968266b87f1d1fecefce5affaeaa624 (2024-07-02)
* DP HIGHLIGHT:
* (TESTING) Tē-Tôo / Map Module
* Road Name Display (Online using OSM)
* Speed Camera Warning (Online using OSM: Untested)
* Speed Camera Warning (Taiwan, Offline)
* Dynamic End-to-End w/ Toggleable Road Condition Detection.
* Device Auto Shutdown Toggle.
* Device Audible Alert Mode Toggle.
dragonpilot [2024.07.01]
=======================
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
const uint8_t gitversion[8] = "3c873995";
const uint8_t gitversion[8] = "3a83aa9c";
+27 -1
View File
@@ -26,7 +26,33 @@ enum LaneChangeAssistMode {
auto @3;
}
struct CustomReserved2 @0xf35cc4560bbf6ec2 {
struct TeToo @0xf35cc4560bbf6ec2 {
lat @0 :Float32;
lon @1 :Float32;
bearing @2 :Float32;
name @3 :Text;
maxspeed @4 :Float32;
tags @5 :Text;
updatingData @6 :Bool;
nearestFeatures @7 :List(Feature);
struct Feature {
id @0 :Text;
type @1 :FeatureType;
lat @2 :Float32;
lon @3 :Float32;
bearing @4 :Float32;
distance @5 :Float32;
tags @6 :Text;
probability @7 :Float32;
}
enum FeatureType {
trafficSignal @0;
speedCamera @1;
}
}
struct CustomReserved3 @0xda96579883444c35 {
+361 -17
View File
@@ -192,32 +192,364 @@ const ::capnp::_::RawSchema s_db95ceb5f50cf43d = {
};
#endif // !CAPNP_LITE
CAPNP_DEFINE_ENUM(LaneChangeAssistMode_db95ceb5f50cf43d, db95ceb5f50cf43d);
static const ::capnp::_::AlignedData<17> b_f35cc4560bbf6ec2 = {
static const ::capnp::_::AlignedData<151> b_f35cc4560bbf6ec2 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
194, 110, 191, 11, 86, 196, 92, 243,
13, 0, 0, 0, 1, 0, 0, 0,
13, 0, 0, 0, 1, 0, 3, 0,
89, 10, 85, 29, 102, 186, 38, 181,
0, 0, 7, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
21, 0, 0, 0, 234, 0, 0, 0,
33, 0, 0, 0, 7, 0, 0, 0,
3, 0, 7, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
21, 0, 0, 0, 154, 0, 0, 0,
29, 0, 0, 0, 39, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
53, 0, 0, 0, 199, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 117, 115, 116, 111, 109, 46, 99,
97, 112, 110, 112, 58, 67, 117, 115,
116, 111, 109, 82, 101, 115, 101, 114,
118, 101, 100, 50, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 1, 0, }
97, 112, 110, 112, 58, 84, 101, 84,
111, 111, 0, 0, 0, 0, 0, 0,
8, 0, 0, 0, 1, 0, 1, 0,
12, 14, 188, 178, 108, 117, 214, 149,
9, 0, 0, 0, 66, 0, 0, 0,
243, 89, 193, 168, 200, 76, 33, 210,
5, 0, 0, 0, 98, 0, 0, 0,
70, 101, 97, 116, 117, 114, 101, 0,
70, 101, 97, 116, 117, 114, 101, 84,
121, 112, 101, 0, 0, 0, 0, 0,
32, 0, 0, 0, 3, 0, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
209, 0, 0, 0, 34, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
204, 0, 0, 0, 3, 0, 1, 0,
216, 0, 0, 0, 2, 0, 1, 0,
1, 0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
213, 0, 0, 0, 34, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
208, 0, 0, 0, 3, 0, 1, 0,
220, 0, 0, 0, 2, 0, 1, 0,
2, 0, 0, 0, 2, 0, 0, 0,
0, 0, 1, 0, 2, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
217, 0, 0, 0, 66, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
212, 0, 0, 0, 3, 0, 1, 0,
224, 0, 0, 0, 2, 0, 1, 0,
3, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 3, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
221, 0, 0, 0, 42, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
216, 0, 0, 0, 3, 0, 1, 0,
228, 0, 0, 0, 2, 0, 1, 0,
4, 0, 0, 0, 3, 0, 0, 0,
0, 0, 1, 0, 4, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
225, 0, 0, 0, 74, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
224, 0, 0, 0, 3, 0, 1, 0,
236, 0, 0, 0, 2, 0, 1, 0,
5, 0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 0, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
233, 0, 0, 0, 42, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
228, 0, 0, 0, 3, 0, 1, 0,
240, 0, 0, 0, 2, 0, 1, 0,
6, 0, 0, 0, 128, 0, 0, 0,
0, 0, 1, 0, 6, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
237, 0, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
236, 0, 0, 0, 3, 0, 1, 0,
248, 0, 0, 0, 2, 0, 1, 0,
7, 0, 0, 0, 2, 0, 0, 0,
0, 0, 1, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
245, 0, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
244, 0, 0, 0, 3, 0, 1, 0,
16, 1, 0, 0, 2, 0, 1, 0,
108, 97, 116, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
108, 111, 110, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
98, 101, 97, 114, 105, 110, 103, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
110, 97, 109, 101, 0, 0, 0, 0,
12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
109, 97, 120, 115, 112, 101, 101, 100,
0, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
116, 97, 103, 115, 0, 0, 0, 0,
12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
117, 112, 100, 97, 116, 105, 110, 103,
68, 97, 116, 97, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
110, 101, 97, 114, 101, 115, 116, 70,
101, 97, 116, 117, 114, 101, 115, 0,
14, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 3, 0, 1, 0,
16, 0, 0, 0, 0, 0, 0, 0,
12, 14, 188, 178, 108, 117, 214, 149,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
14, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_f35cc4560bbf6ec2 = b_f35cc4560bbf6ec2.words;
#if !CAPNP_LITE
static const ::capnp::_::RawSchema* const d_f35cc4560bbf6ec2[] = {
&s_95d6756cb2bc0e0c,
};
static const uint16_t m_f35cc4560bbf6ec2[] = {2, 0, 1, 4, 3, 7, 5, 6};
static const uint16_t i_f35cc4560bbf6ec2[] = {0, 1, 2, 3, 4, 5, 6, 7};
const ::capnp::_::RawSchema s_f35cc4560bbf6ec2 = {
0xf35cc4560bbf6ec2, b_f35cc4560bbf6ec2.words, 17, nullptr, nullptr,
0, 0, nullptr, nullptr, nullptr, { &s_f35cc4560bbf6ec2, nullptr, nullptr, 0, 0, nullptr }, false
0xf35cc4560bbf6ec2, b_f35cc4560bbf6ec2.words, 151, d_f35cc4560bbf6ec2, m_f35cc4560bbf6ec2,
1, 8, i_f35cc4560bbf6ec2, nullptr, nullptr, { &s_f35cc4560bbf6ec2, nullptr, nullptr, 0, 0, nullptr }, false
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<140> b_95d6756cb2bc0e0c = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
12, 14, 188, 178, 108, 117, 214, 149,
19, 0, 0, 0, 1, 0, 3, 0,
194, 110, 191, 11, 86, 196, 92, 243,
2, 0, 7, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
21, 0, 0, 0, 218, 0, 0, 0,
33, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
29, 0, 0, 0, 199, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 117, 115, 116, 111, 109, 46, 99,
97, 112, 110, 112, 58, 84, 101, 84,
111, 111, 46, 70, 101, 97, 116, 117,
114, 101, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 1, 0,
32, 0, 0, 0, 3, 0, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
209, 0, 0, 0, 26, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
204, 0, 0, 0, 3, 0, 1, 0,
216, 0, 0, 0, 2, 0, 1, 0,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
213, 0, 0, 0, 42, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
208, 0, 0, 0, 3, 0, 1, 0,
220, 0, 0, 0, 2, 0, 1, 0,
2, 0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 0, 2, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
217, 0, 0, 0, 34, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
212, 0, 0, 0, 3, 0, 1, 0,
224, 0, 0, 0, 2, 0, 1, 0,
3, 0, 0, 0, 2, 0, 0, 0,
0, 0, 1, 0, 3, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
221, 0, 0, 0, 34, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
216, 0, 0, 0, 3, 0, 1, 0,
228, 0, 0, 0, 2, 0, 1, 0,
4, 0, 0, 0, 3, 0, 0, 0,
0, 0, 1, 0, 4, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
225, 0, 0, 0, 66, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
220, 0, 0, 0, 3, 0, 1, 0,
232, 0, 0, 0, 2, 0, 1, 0,
5, 0, 0, 0, 4, 0, 0, 0,
0, 0, 1, 0, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
229, 0, 0, 0, 74, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
228, 0, 0, 0, 3, 0, 1, 0,
240, 0, 0, 0, 2, 0, 1, 0,
6, 0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 0, 6, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
237, 0, 0, 0, 42, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
232, 0, 0, 0, 3, 0, 1, 0,
244, 0, 0, 0, 2, 0, 1, 0,
7, 0, 0, 0, 5, 0, 0, 0,
0, 0, 1, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
241, 0, 0, 0, 98, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
240, 0, 0, 0, 3, 0, 1, 0,
252, 0, 0, 0, 2, 0, 1, 0,
105, 100, 0, 0, 0, 0, 0, 0,
12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
116, 121, 112, 101, 0, 0, 0, 0,
15, 0, 0, 0, 0, 0, 0, 0,
243, 89, 193, 168, 200, 76, 33, 210,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
15, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
108, 97, 116, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
108, 111, 110, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
98, 101, 97, 114, 105, 110, 103, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
100, 105, 115, 116, 97, 110, 99, 101,
0, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
116, 97, 103, 115, 0, 0, 0, 0,
12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
112, 114, 111, 98, 97, 98, 105, 108,
105, 116, 121, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_95d6756cb2bc0e0c = b_95d6756cb2bc0e0c.words;
#if !CAPNP_LITE
static const ::capnp::_::RawSchema* const d_95d6756cb2bc0e0c[] = {
&s_d2214cc8a8c159f3,
};
static const uint16_t m_95d6756cb2bc0e0c[] = {4, 5, 0, 2, 3, 7, 6, 1};
static const uint16_t i_95d6756cb2bc0e0c[] = {0, 1, 2, 3, 4, 5, 6, 7};
const ::capnp::_::RawSchema s_95d6756cb2bc0e0c = {
0x95d6756cb2bc0e0c, b_95d6756cb2bc0e0c.words, 140, d_95d6756cb2bc0e0c, m_95d6756cb2bc0e0c,
1, 8, i_95d6756cb2bc0e0c, nullptr, nullptr, { &s_95d6756cb2bc0e0c, nullptr, nullptr, 0, 0, nullptr }, false
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<28> b_d2214cc8a8c159f3 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
243, 89, 193, 168, 200, 76, 33, 210,
19, 0, 0, 0, 2, 0, 0, 0,
194, 110, 191, 11, 86, 196, 92, 243,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
21, 0, 0, 0, 250, 0, 0, 0,
33, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
29, 0, 0, 0, 55, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 117, 115, 116, 111, 109, 46, 99,
97, 112, 110, 112, 58, 84, 101, 84,
111, 111, 46, 70, 101, 97, 116, 117,
114, 101, 84, 121, 112, 101, 0, 0,
0, 0, 0, 0, 1, 0, 1, 0,
8, 0, 0, 0, 1, 0, 2, 0,
0, 0, 0, 0, 0, 0, 0, 0,
17, 0, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
13, 0, 0, 0, 98, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
116, 114, 97, 102, 102, 105, 99, 83,
105, 103, 110, 97, 108, 0, 0, 0,
115, 112, 101, 101, 100, 67, 97, 109,
101, 114, 97, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_d2214cc8a8c159f3 = b_d2214cc8a8c159f3.words;
#if !CAPNP_LITE
static const uint16_t m_d2214cc8a8c159f3[] = {1, 0};
const ::capnp::_::RawSchema s_d2214cc8a8c159f3 = {
0xd2214cc8a8c159f3, b_d2214cc8a8c159f3.words, 28, nullptr, m_d2214cc8a8c159f3,
0, 2, nullptr, nullptr, nullptr, { &s_d2214cc8a8c159f3, nullptr, nullptr, 0, 0, nullptr }, false
};
#endif // !CAPNP_LITE
CAPNP_DEFINE_ENUM(FeatureType_d2214cc8a8c159f3, d2214cc8a8c159f3);
static const ::capnp::_::AlignedData<17> b_da96579883444c35 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
53, 76, 68, 131, 152, 87, 150, 218,
@@ -431,15 +763,27 @@ constexpr ::capnp::_::RawSchema const* LongitudinalPlanExt::_capnpPrivate::schem
#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL
#endif // !CAPNP_LITE
// CustomReserved2
// TeToo
#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr uint16_t CustomReserved2::_capnpPrivate::dataWordSize;
constexpr uint16_t CustomReserved2::_capnpPrivate::pointerCount;
constexpr uint16_t TeToo::_capnpPrivate::dataWordSize;
constexpr uint16_t TeToo::_capnpPrivate::pointerCount;
#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL
#if !CAPNP_LITE
#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr ::capnp::Kind CustomReserved2::_capnpPrivate::kind;
constexpr ::capnp::_::RawSchema const* CustomReserved2::_capnpPrivate::schema;
constexpr ::capnp::Kind TeToo::_capnpPrivate::kind;
constexpr ::capnp::_::RawSchema const* TeToo::_capnpPrivate::schema;
#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL
#endif // !CAPNP_LITE
// TeToo::Feature
#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr uint16_t TeToo::Feature::_capnpPrivate::dataWordSize;
constexpr uint16_t TeToo::Feature::_capnpPrivate::pointerCount;
#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL
#if !CAPNP_LITE
#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr ::capnp::Kind TeToo::Feature::_capnpPrivate::kind;
constexpr ::capnp::_::RawSchema const* TeToo::Feature::_capnpPrivate::schema;
#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL
#endif // !CAPNP_LITE
+534 -9
View File
@@ -29,6 +29,13 @@ enum class LaneChangeAssistMode_db95ceb5f50cf43d: uint16_t {
};
CAPNP_DECLARE_ENUM(LaneChangeAssistMode, db95ceb5f50cf43d);
CAPNP_DECLARE_SCHEMA(f35cc4560bbf6ec2);
CAPNP_DECLARE_SCHEMA(95d6756cb2bc0e0c);
CAPNP_DECLARE_SCHEMA(d2214cc8a8c159f3);
enum class FeatureType_d2214cc8a8c159f3: uint16_t {
TRAFFIC_SIGNAL,
SPEED_CAMERA,
};
CAPNP_DECLARE_ENUM(FeatureType, d2214cc8a8c159f3);
CAPNP_DECLARE_SCHEMA(da96579883444c35);
CAPNP_DECLARE_SCHEMA(80ae746ee2596b11);
CAPNP_DECLARE_SCHEMA(a5cd762cd951a455);
@@ -74,15 +81,33 @@ struct LongitudinalPlanExt {
typedef ::capnp::schemas::LaneChangeAssistMode_db95ceb5f50cf43d LaneChangeAssistMode;
struct CustomReserved2 {
CustomReserved2() = delete;
struct TeToo {
TeToo() = delete;
class Reader;
class Builder;
class Pipeline;
struct Feature;
typedef ::capnp::schemas::FeatureType_d2214cc8a8c159f3 FeatureType;
struct _capnpPrivate {
CAPNP_DECLARE_STRUCT_HEADER(f35cc4560bbf6ec2, 3, 3)
#if !CAPNP_LITE
static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
#endif // !CAPNP_LITE
};
};
struct TeToo::Feature {
Feature() = delete;
class Reader;
class Builder;
class Pipeline;
struct _capnpPrivate {
CAPNP_DECLARE_STRUCT_HEADER(f35cc4560bbf6ec2, 0, 0)
CAPNP_DECLARE_STRUCT_HEADER(95d6756cb2bc0e0c, 3, 2)
#if !CAPNP_LITE
static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
#endif // !CAPNP_LITE
@@ -363,9 +388,9 @@ private:
};
#endif // !CAPNP_LITE
class CustomReserved2::Reader {
class TeToo::Reader {
public:
typedef CustomReserved2 Reads;
typedef TeToo Reads;
Reader() = default;
inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}
@@ -380,6 +405,25 @@ public:
}
#endif // !CAPNP_LITE
inline float getLat() const;
inline float getLon() const;
inline float getBearing() const;
inline bool hasName() const;
inline ::capnp::Text::Reader getName() const;
inline float getMaxspeed() const;
inline bool hasTags() const;
inline ::capnp::Text::Reader getTags() const;
inline bool getUpdatingData() const;
inline bool hasNearestFeatures() const;
inline ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>::Reader getNearestFeatures() const;
private:
::capnp::_::StructReader _reader;
template <typename, ::capnp::Kind>
@@ -392,9 +436,9 @@ private:
friend class ::capnp::Orphanage;
};
class CustomReserved2::Builder {
class TeToo::Builder {
public:
typedef CustomReserved2 Builds;
typedef TeToo Builds;
Builder() = delete; // Deleted to discourage incorrect usage.
// You can explicitly initialize to nullptr instead.
@@ -408,6 +452,42 @@ public:
inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif // !CAPNP_LITE
inline float getLat();
inline void setLat(float value);
inline float getLon();
inline void setLon(float value);
inline float getBearing();
inline void setBearing(float value);
inline bool hasName();
inline ::capnp::Text::Builder getName();
inline void setName( ::capnp::Text::Reader value);
inline ::capnp::Text::Builder initName(unsigned int size);
inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value);
inline ::capnp::Orphan< ::capnp::Text> disownName();
inline float getMaxspeed();
inline void setMaxspeed(float value);
inline bool hasTags();
inline ::capnp::Text::Builder getTags();
inline void setTags( ::capnp::Text::Reader value);
inline ::capnp::Text::Builder initTags(unsigned int size);
inline void adoptTags(::capnp::Orphan< ::capnp::Text>&& value);
inline ::capnp::Orphan< ::capnp::Text> disownTags();
inline bool getUpdatingData();
inline void setUpdatingData(bool value);
inline bool hasNearestFeatures();
inline ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>::Builder getNearestFeatures();
inline void setNearestFeatures( ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>::Reader value);
inline ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>::Builder initNearestFeatures(unsigned int size);
inline void adoptNearestFeatures(::capnp::Orphan< ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>>&& value);
inline ::capnp::Orphan< ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>> disownNearestFeatures();
private:
::capnp::_::StructBuilder _builder;
template <typename, ::capnp::Kind>
@@ -418,9 +498,130 @@ private:
};
#if !CAPNP_LITE
class CustomReserved2::Pipeline {
class TeToo::Pipeline {
public:
typedef CustomReserved2 Pipelines;
typedef TeToo Pipelines;
inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
: _typeless(kj::mv(typeless)) {}
private:
::capnp::AnyPointer::Pipeline _typeless;
friend class ::capnp::PipelineHook;
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
};
#endif // !CAPNP_LITE
class TeToo::Feature::Reader {
public:
typedef Feature Reads;
Reader() = default;
inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}
inline ::capnp::MessageSize totalSize() const {
return _reader.totalSize().asPublic();
}
#if !CAPNP_LITE
inline ::kj::StringTree toString() const {
return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
}
#endif // !CAPNP_LITE
inline bool hasId() const;
inline ::capnp::Text::Reader getId() const;
inline ::cereal::TeToo::FeatureType getType() const;
inline float getLat() const;
inline float getLon() const;
inline float getBearing() const;
inline float getDistance() const;
inline bool hasTags() const;
inline ::capnp::Text::Reader getTags() const;
inline float getProbability() const;
private:
::capnp::_::StructReader _reader;
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
template <typename, ::capnp::Kind>
friend struct ::capnp::_::PointerHelpers;
template <typename, ::capnp::Kind>
friend struct ::capnp::List;
friend class ::capnp::MessageBuilder;
friend class ::capnp::Orphanage;
};
class TeToo::Feature::Builder {
public:
typedef Feature Builds;
Builder() = delete; // Deleted to discourage incorrect usage.
// You can explicitly initialize to nullptr instead.
inline Builder(decltype(nullptr)) {}
inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
inline operator Reader() const { return Reader(_builder.asReader()); }
inline Reader asReader() const { return *this; }
inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif // !CAPNP_LITE
inline bool hasId();
inline ::capnp::Text::Builder getId();
inline void setId( ::capnp::Text::Reader value);
inline ::capnp::Text::Builder initId(unsigned int size);
inline void adoptId(::capnp::Orphan< ::capnp::Text>&& value);
inline ::capnp::Orphan< ::capnp::Text> disownId();
inline ::cereal::TeToo::FeatureType getType();
inline void setType( ::cereal::TeToo::FeatureType value);
inline float getLat();
inline void setLat(float value);
inline float getLon();
inline void setLon(float value);
inline float getBearing();
inline void setBearing(float value);
inline float getDistance();
inline void setDistance(float value);
inline bool hasTags();
inline ::capnp::Text::Builder getTags();
inline void setTags( ::capnp::Text::Reader value);
inline ::capnp::Text::Builder initTags(unsigned int size);
inline void adoptTags(::capnp::Orphan< ::capnp::Text>&& value);
inline ::capnp::Orphan< ::capnp::Text> disownTags();
inline float getProbability();
inline void setProbability(float value);
private:
::capnp::_::StructBuilder _builder;
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
friend class ::capnp::Orphanage;
template <typename, ::capnp::Kind>
friend struct ::capnp::_::PointerHelpers;
};
#if !CAPNP_LITE
class TeToo::Feature::Pipeline {
public:
typedef Feature Pipelines;
inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
@@ -1003,6 +1204,330 @@ inline void LongitudinalPlanExt::Builder::setAltDrivingPersonalityIsActive(bool
::capnp::bounded<2>() * ::capnp::ELEMENTS, value);
}
inline float TeToo::Reader::getLat() const {
return _reader.getDataField<float>(
::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline float TeToo::Builder::getLat() {
return _builder.getDataField<float>(
::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void TeToo::Builder::setLat(float value) {
_builder.setDataField<float>(
::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}
inline float TeToo::Reader::getLon() const {
return _reader.getDataField<float>(
::capnp::bounded<1>() * ::capnp::ELEMENTS);
}
inline float TeToo::Builder::getLon() {
return _builder.getDataField<float>(
::capnp::bounded<1>() * ::capnp::ELEMENTS);
}
inline void TeToo::Builder::setLon(float value) {
_builder.setDataField<float>(
::capnp::bounded<1>() * ::capnp::ELEMENTS, value);
}
inline float TeToo::Reader::getBearing() const {
return _reader.getDataField<float>(
::capnp::bounded<2>() * ::capnp::ELEMENTS);
}
inline float TeToo::Builder::getBearing() {
return _builder.getDataField<float>(
::capnp::bounded<2>() * ::capnp::ELEMENTS);
}
inline void TeToo::Builder::setBearing(float value) {
_builder.setDataField<float>(
::capnp::bounded<2>() * ::capnp::ELEMENTS, value);
}
inline bool TeToo::Reader::hasName() const {
return !_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool TeToo::Builder::hasName() {
return !_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::Text::Reader TeToo::Reader::getName() const {
return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::Text::Builder TeToo::Builder::getName() {
return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void TeToo::Builder::setName( ::capnp::Text::Reader value) {
::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline ::capnp::Text::Builder TeToo::Builder::initName(unsigned int size) {
return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), size);
}
inline void TeToo::Builder::adoptName(
::capnp::Orphan< ::capnp::Text>&& value) {
::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> TeToo::Builder::disownName() {
return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline float TeToo::Reader::getMaxspeed() const {
return _reader.getDataField<float>(
::capnp::bounded<3>() * ::capnp::ELEMENTS);
}
inline float TeToo::Builder::getMaxspeed() {
return _builder.getDataField<float>(
::capnp::bounded<3>() * ::capnp::ELEMENTS);
}
inline void TeToo::Builder::setMaxspeed(float value) {
_builder.setDataField<float>(
::capnp::bounded<3>() * ::capnp::ELEMENTS, value);
}
inline bool TeToo::Reader::hasTags() const {
return !_reader.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline bool TeToo::Builder::hasTags() {
return !_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::Text::Reader TeToo::Reader::getTags() const {
return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline ::capnp::Text::Builder TeToo::Builder::getTags() {
return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline void TeToo::Builder::setTags( ::capnp::Text::Reader value) {
::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS), value);
}
inline ::capnp::Text::Builder TeToo::Builder::initTags(unsigned int size) {
return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS), size);
}
inline void TeToo::Builder::adoptTags(
::capnp::Orphan< ::capnp::Text>&& value) {
::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> TeToo::Builder::disownTags() {
return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline bool TeToo::Reader::getUpdatingData() const {
return _reader.getDataField<bool>(
::capnp::bounded<128>() * ::capnp::ELEMENTS);
}
inline bool TeToo::Builder::getUpdatingData() {
return _builder.getDataField<bool>(
::capnp::bounded<128>() * ::capnp::ELEMENTS);
}
inline void TeToo::Builder::setUpdatingData(bool value) {
_builder.setDataField<bool>(
::capnp::bounded<128>() * ::capnp::ELEMENTS, value);
}
inline bool TeToo::Reader::hasNearestFeatures() const {
return !_reader.getPointerField(
::capnp::bounded<2>() * ::capnp::POINTERS).isNull();
}
inline bool TeToo::Builder::hasNearestFeatures() {
return !_builder.getPointerField(
::capnp::bounded<2>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>::Reader TeToo::Reader::getNearestFeatures() const {
return ::capnp::_::PointerHelpers< ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField(
::capnp::bounded<2>() * ::capnp::POINTERS));
}
inline ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>::Builder TeToo::Builder::getNearestFeatures() {
return ::capnp::_::PointerHelpers< ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField(
::capnp::bounded<2>() * ::capnp::POINTERS));
}
inline void TeToo::Builder::setNearestFeatures( ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>::Reader value) {
::capnp::_::PointerHelpers< ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField(
::capnp::bounded<2>() * ::capnp::POINTERS), value);
}
inline ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>::Builder TeToo::Builder::initNearestFeatures(unsigned int size) {
return ::capnp::_::PointerHelpers< ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField(
::capnp::bounded<2>() * ::capnp::POINTERS), size);
}
inline void TeToo::Builder::adoptNearestFeatures(
::capnp::Orphan< ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>>&& value) {
::capnp::_::PointerHelpers< ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField(
::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>> TeToo::Builder::disownNearestFeatures() {
return ::capnp::_::PointerHelpers< ::capnp::List< ::cereal::TeToo::Feature, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField(
::capnp::bounded<2>() * ::capnp::POINTERS));
}
inline bool TeToo::Feature::Reader::hasId() const {
return !_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool TeToo::Feature::Builder::hasId() {
return !_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::Text::Reader TeToo::Feature::Reader::getId() const {
return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::Text::Builder TeToo::Feature::Builder::getId() {
return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void TeToo::Feature::Builder::setId( ::capnp::Text::Reader value) {
::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline ::capnp::Text::Builder TeToo::Feature::Builder::initId(unsigned int size) {
return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), size);
}
inline void TeToo::Feature::Builder::adoptId(
::capnp::Orphan< ::capnp::Text>&& value) {
::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> TeToo::Feature::Builder::disownId() {
return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::cereal::TeToo::FeatureType TeToo::Feature::Reader::getType() const {
return _reader.getDataField< ::cereal::TeToo::FeatureType>(
::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline ::cereal::TeToo::FeatureType TeToo::Feature::Builder::getType() {
return _builder.getDataField< ::cereal::TeToo::FeatureType>(
::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void TeToo::Feature::Builder::setType( ::cereal::TeToo::FeatureType value) {
_builder.setDataField< ::cereal::TeToo::FeatureType>(
::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}
inline float TeToo::Feature::Reader::getLat() const {
return _reader.getDataField<float>(
::capnp::bounded<1>() * ::capnp::ELEMENTS);
}
inline float TeToo::Feature::Builder::getLat() {
return _builder.getDataField<float>(
::capnp::bounded<1>() * ::capnp::ELEMENTS);
}
inline void TeToo::Feature::Builder::setLat(float value) {
_builder.setDataField<float>(
::capnp::bounded<1>() * ::capnp::ELEMENTS, value);
}
inline float TeToo::Feature::Reader::getLon() const {
return _reader.getDataField<float>(
::capnp::bounded<2>() * ::capnp::ELEMENTS);
}
inline float TeToo::Feature::Builder::getLon() {
return _builder.getDataField<float>(
::capnp::bounded<2>() * ::capnp::ELEMENTS);
}
inline void TeToo::Feature::Builder::setLon(float value) {
_builder.setDataField<float>(
::capnp::bounded<2>() * ::capnp::ELEMENTS, value);
}
inline float TeToo::Feature::Reader::getBearing() const {
return _reader.getDataField<float>(
::capnp::bounded<3>() * ::capnp::ELEMENTS);
}
inline float TeToo::Feature::Builder::getBearing() {
return _builder.getDataField<float>(
::capnp::bounded<3>() * ::capnp::ELEMENTS);
}
inline void TeToo::Feature::Builder::setBearing(float value) {
_builder.setDataField<float>(
::capnp::bounded<3>() * ::capnp::ELEMENTS, value);
}
inline float TeToo::Feature::Reader::getDistance() const {
return _reader.getDataField<float>(
::capnp::bounded<4>() * ::capnp::ELEMENTS);
}
inline float TeToo::Feature::Builder::getDistance() {
return _builder.getDataField<float>(
::capnp::bounded<4>() * ::capnp::ELEMENTS);
}
inline void TeToo::Feature::Builder::setDistance(float value) {
_builder.setDataField<float>(
::capnp::bounded<4>() * ::capnp::ELEMENTS, value);
}
inline bool TeToo::Feature::Reader::hasTags() const {
return !_reader.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline bool TeToo::Feature::Builder::hasTags() {
return !_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::Text::Reader TeToo::Feature::Reader::getTags() const {
return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline ::capnp::Text::Builder TeToo::Feature::Builder::getTags() {
return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline void TeToo::Feature::Builder::setTags( ::capnp::Text::Reader value) {
::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS), value);
}
inline ::capnp::Text::Builder TeToo::Feature::Builder::initTags(unsigned int size) {
return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS), size);
}
inline void TeToo::Feature::Builder::adoptTags(
::capnp::Orphan< ::capnp::Text>&& value) {
::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> TeToo::Feature::Builder::disownTags() {
return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline float TeToo::Feature::Reader::getProbability() const {
return _reader.getDataField<float>(
::capnp::bounded<5>() * ::capnp::ELEMENTS);
}
inline float TeToo::Feature::Builder::getProbability() {
return _builder.getDataField<float>(
::capnp::bounded<5>() * ::capnp::ELEMENTS);
}
inline void TeToo::Feature::Builder::setProbability(float value) {
_builder.setDataField<float>(
::capnp::bounded<5>() * ::capnp::ELEMENTS, value);
}
} // namespace
CAPNP_END_HEADER
+64 -65
View File
@@ -27868,7 +27868,7 @@ const ::capnp::_::RawSchema s_dc24138990726023 = {
0, 4, i_dc24138990726023, nullptr, nullptr, { &s_dc24138990726023, nullptr, nullptr, 0, 0, nullptr }, false
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<2199> b_d314cfd957229c11 = {
static const ::capnp::_::AlignedData<2198> b_d314cfd957229c11 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
17, 156, 34, 87, 217, 207, 20, 211,
10, 0, 0, 0, 1, 0, 2, 0,
@@ -28651,143 +28651,143 @@ static const ::capnp::_::AlignedData<2199> b_d314cfd957229c11 = {
81, 0, 148, 255, 0, 0, 0, 0,
0, 0, 1, 0, 109, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
17, 19, 0, 0, 130, 0, 0, 0,
17, 19, 0, 0, 50, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
16, 19, 0, 0, 3, 0, 1, 0,
28, 19, 0, 0, 2, 0, 1, 0,
12, 19, 0, 0, 3, 0, 1, 0,
24, 19, 0, 0, 2, 0, 1, 0,
82, 0, 147, 255, 0, 0, 0, 0,
0, 0, 1, 0, 110, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
25, 19, 0, 0, 130, 0, 0, 0,
21, 19, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
24, 19, 0, 0, 3, 0, 1, 0,
36, 19, 0, 0, 2, 0, 1, 0,
20, 19, 0, 0, 3, 0, 1, 0,
32, 19, 0, 0, 2, 0, 1, 0,
83, 0, 146, 255, 0, 0, 0, 0,
0, 0, 1, 0, 111, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
33, 19, 0, 0, 130, 0, 0, 0,
29, 19, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
32, 19, 0, 0, 3, 0, 1, 0,
44, 19, 0, 0, 2, 0, 1, 0,
28, 19, 0, 0, 3, 0, 1, 0,
40, 19, 0, 0, 2, 0, 1, 0,
84, 0, 145, 255, 0, 0, 0, 0,
0, 0, 1, 0, 112, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
41, 19, 0, 0, 130, 0, 0, 0,
37, 19, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
40, 19, 0, 0, 3, 0, 1, 0,
52, 19, 0, 0, 2, 0, 1, 0,
36, 19, 0, 0, 3, 0, 1, 0,
48, 19, 0, 0, 2, 0, 1, 0,
85, 0, 144, 255, 0, 0, 0, 0,
0, 0, 1, 0, 113, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
49, 19, 0, 0, 130, 0, 0, 0,
45, 19, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
48, 19, 0, 0, 3, 0, 1, 0,
60, 19, 0, 0, 2, 0, 1, 0,
44, 19, 0, 0, 3, 0, 1, 0,
56, 19, 0, 0, 2, 0, 1, 0,
86, 0, 143, 255, 0, 0, 0, 0,
0, 0, 1, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
57, 19, 0, 0, 130, 0, 0, 0,
53, 19, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
56, 19, 0, 0, 3, 0, 1, 0,
68, 19, 0, 0, 2, 0, 1, 0,
52, 19, 0, 0, 3, 0, 1, 0,
64, 19, 0, 0, 2, 0, 1, 0,
87, 0, 142, 255, 0, 0, 0, 0,
0, 0, 1, 0, 115, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
65, 19, 0, 0, 130, 0, 0, 0,
61, 19, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
64, 19, 0, 0, 3, 0, 1, 0,
76, 19, 0, 0, 2, 0, 1, 0,
60, 19, 0, 0, 3, 0, 1, 0,
72, 19, 0, 0, 2, 0, 1, 0,
88, 0, 141, 255, 0, 0, 0, 0,
0, 0, 1, 0, 116, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
73, 19, 0, 0, 130, 0, 0, 0,
69, 19, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
72, 19, 0, 0, 3, 0, 1, 0,
84, 19, 0, 0, 2, 0, 1, 0,
68, 19, 0, 0, 3, 0, 1, 0,
80, 19, 0, 0, 2, 0, 1, 0,
50, 0, 140, 255, 0, 0, 0, 0,
0, 0, 1, 0, 117, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
81, 19, 0, 0, 194, 0, 0, 0,
77, 19, 0, 0, 194, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
84, 19, 0, 0, 3, 0, 1, 0,
96, 19, 0, 0, 2, 0, 1, 0,
80, 19, 0, 0, 3, 0, 1, 0,
92, 19, 0, 0, 2, 0, 1, 0,
51, 0, 139, 255, 0, 0, 0, 0,
0, 0, 1, 0, 118, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
93, 19, 0, 0, 226, 0, 0, 0,
89, 19, 0, 0, 226, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
100, 19, 0, 0, 3, 0, 1, 0,
112, 19, 0, 0, 2, 0, 1, 0,
96, 19, 0, 0, 3, 0, 1, 0,
108, 19, 0, 0, 2, 0, 1, 0,
52, 0, 138, 255, 0, 0, 0, 0,
0, 0, 1, 0, 119, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
109, 19, 0, 0, 210, 0, 0, 0,
105, 19, 0, 0, 210, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
116, 19, 0, 0, 3, 0, 1, 0,
128, 19, 0, 0, 2, 0, 1, 0,
112, 19, 0, 0, 3, 0, 1, 0,
124, 19, 0, 0, 2, 0, 1, 0,
73, 0, 137, 255, 0, 0, 0, 0,
0, 0, 1, 0, 120, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
125, 19, 0, 0, 202, 0, 0, 0,
121, 19, 0, 0, 202, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
132, 19, 0, 0, 3, 0, 1, 0,
144, 19, 0, 0, 2, 0, 1, 0,
128, 19, 0, 0, 3, 0, 1, 0,
140, 19, 0, 0, 2, 0, 1, 0,
74, 0, 136, 255, 0, 0, 0, 0,
0, 0, 1, 0, 121, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
141, 19, 0, 0, 234, 0, 0, 0,
137, 19, 0, 0, 234, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
148, 19, 0, 0, 3, 0, 1, 0,
160, 19, 0, 0, 2, 0, 1, 0,
144, 19, 0, 0, 3, 0, 1, 0,
156, 19, 0, 0, 2, 0, 1, 0,
75, 0, 135, 255, 0, 0, 0, 0,
0, 0, 1, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
157, 19, 0, 0, 218, 0, 0, 0,
153, 19, 0, 0, 218, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
164, 19, 0, 0, 3, 0, 1, 0,
176, 19, 0, 0, 2, 0, 1, 0,
160, 19, 0, 0, 3, 0, 1, 0,
172, 19, 0, 0, 2, 0, 1, 0,
15, 0, 134, 255, 0, 0, 0, 0,
0, 0, 1, 0, 123, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
173, 19, 0, 0, 154, 0, 0, 0,
169, 19, 0, 0, 154, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
176, 19, 0, 0, 3, 0, 1, 0,
188, 19, 0, 0, 2, 0, 1, 0,
172, 19, 0, 0, 3, 0, 1, 0,
184, 19, 0, 0, 2, 0, 1, 0,
76, 0, 133, 255, 0, 0, 0, 0,
0, 0, 1, 0, 124, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
185, 19, 0, 0, 186, 0, 0, 0,
181, 19, 0, 0, 186, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
188, 19, 0, 0, 3, 0, 1, 0,
200, 19, 0, 0, 2, 0, 1, 0,
184, 19, 0, 0, 3, 0, 1, 0,
196, 19, 0, 0, 2, 0, 1, 0,
77, 0, 132, 255, 0, 0, 0, 0,
0, 0, 1, 0, 125, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
197, 19, 0, 0, 186, 0, 0, 0,
193, 19, 0, 0, 186, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
200, 19, 0, 0, 3, 0, 1, 0,
212, 19, 0, 0, 2, 0, 1, 0,
196, 19, 0, 0, 3, 0, 1, 0,
208, 19, 0, 0, 2, 0, 1, 0,
78, 0, 131, 255, 0, 0, 0, 0,
0, 0, 1, 0, 126, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
209, 19, 0, 0, 186, 0, 0, 0,
205, 19, 0, 0, 186, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
212, 19, 0, 0, 3, 0, 1, 0,
224, 19, 0, 0, 2, 0, 1, 0,
208, 19, 0, 0, 3, 0, 1, 0,
220, 19, 0, 0, 2, 0, 1, 0,
24, 0, 130, 255, 0, 0, 0, 0,
0, 0, 1, 0, 127, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
221, 19, 0, 0, 82, 0, 0, 0,
217, 19, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
220, 19, 0, 0, 3, 0, 1, 0,
232, 19, 0, 0, 2, 0, 1, 0,
216, 19, 0, 0, 3, 0, 1, 0,
228, 19, 0, 0, 2, 0, 1, 0,
41, 0, 129, 255, 0, 0, 0, 0,
0, 0, 1, 0, 128, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
229, 19, 0, 0, 138, 0, 0, 0,
225, 19, 0, 0, 138, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
232, 19, 0, 0, 3, 0, 1, 0,
244, 19, 0, 0, 2, 0, 1, 0,
228, 19, 0, 0, 3, 0, 1, 0,
240, 19, 0, 0, 2, 0, 1, 0,
108, 111, 103, 77, 111, 110, 111, 84,
105, 109, 101, 0, 0, 0, 0, 0,
9, 0, 0, 0, 0, 0, 0, 0,
@@ -29872,8 +29872,7 @@ static const ::capnp::_::AlignedData<2199> b_d314cfd957229c11 = {
16, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 117, 115, 116, 111, 109, 82, 101,
115, 101, 114, 118, 101, 100, 50, 0,
116, 101, 84, 111, 111, 0, 0, 0,
16, 0, 0, 0, 0, 0, 0, 0,
194, 110, 191, 11, 86, 196, 92, 243,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -30161,10 +30160,10 @@ static const ::capnp::_::RawSchema* const d_d314cfd957229c11[] = {
&s_fe346a9de48d9b50,
&s_fe35ad896ffaeacf,
};
static const uint16_t m_d314cfd957229c11[] = {98, 101, 30, 20, 55, 42, 60, 63, 5, 23, 127, 69, 22, 28, 35, 7, 107, 109, 110, 111, 112, 113, 114, 115, 116, 124, 125, 126, 6, 70, 87, 76, 71, 59, 92, 128, 85, 26, 10, 91, 21, 48, 3, 41, 40, 99, 100, 1, 65, 64, 32, 96, 19, 8, 46, 25, 72, 51, 44, 37, 62, 36, 61, 94, 16, 14, 122, 119, 120, 117, 121, 118, 49, 18, 0, 24, 108, 95, 78, 105, 103, 9, 75, 82, 104, 83, 38, 84, 27, 68, 54, 58, 56, 47, 53, 45, 12, 81, 80, 33, 89, 90, 31, 13, 2, 86, 15, 17, 4, 11, 73, 97, 123, 52, 66, 43, 34, 39, 102, 57, 50, 106, 79, 93, 67, 74, 88, 77, 29};
static const uint16_t m_d314cfd957229c11[] = {98, 101, 30, 20, 55, 42, 60, 63, 5, 23, 127, 69, 22, 28, 35, 7, 107, 110, 111, 112, 113, 114, 115, 116, 124, 125, 126, 6, 70, 87, 76, 71, 59, 92, 128, 85, 26, 10, 91, 21, 48, 3, 41, 40, 99, 100, 1, 65, 64, 32, 96, 19, 8, 46, 25, 72, 51, 44, 37, 62, 36, 61, 94, 16, 14, 122, 119, 120, 117, 121, 118, 49, 18, 0, 24, 108, 95, 78, 105, 103, 9, 75, 82, 104, 83, 38, 84, 27, 68, 54, 58, 56, 47, 53, 45, 12, 81, 80, 33, 89, 90, 31, 13, 2, 86, 15, 17, 4, 11, 73, 109, 97, 123, 52, 66, 43, 34, 39, 102, 57, 50, 106, 79, 93, 67, 74, 88, 77, 29};
static const uint16_t i_d314cfd957229c11[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 0, 67};
const ::capnp::_::RawSchema s_d314cfd957229c11 = {
0xd314cfd957229c11, b_d314cfd957229c11.words, 2199, d_d314cfd957229c11, m_d314cfd957229c11,
0xd314cfd957229c11, b_d314cfd957229c11.words, 2198, d_d314cfd957229c11, m_d314cfd957229c11,
88, 129, i_d314cfd957229c11, nullptr, nullptr, { &s_d314cfd957229c11, nullptr, nullptr, 0, 0, nullptr }, true
};
#endif // !CAPNP_LITE
+38 -38
View File
@@ -2544,7 +2544,7 @@ struct Event {
UI_PLAN_D_E_P_R_E_C_A_T_E_D,
CONTROLS_STATE_EXT,
LONGITUDINAL_PLAN_EXT,
CUSTOM_RESERVED2,
TE_TOO,
CUSTOM_RESERVED3,
CUSTOM_RESERVED4,
CUSTOM_RESERVED5,
@@ -19684,9 +19684,9 @@ public:
inline bool hasLongitudinalPlanExt() const;
inline ::cereal::LongitudinalPlanExt::Reader getLongitudinalPlanExt() const;
inline bool isCustomReserved2() const;
inline bool hasCustomReserved2() const;
inline ::cereal::CustomReserved2::Reader getCustomReserved2() const;
inline bool isTeToo() const;
inline bool hasTeToo() const;
inline ::cereal::TeToo::Reader getTeToo() const;
inline bool isCustomReserved3() const;
inline bool hasCustomReserved3() const;
@@ -20655,13 +20655,13 @@ public:
inline void adoptLongitudinalPlanExt(::capnp::Orphan< ::cereal::LongitudinalPlanExt>&& value);
inline ::capnp::Orphan< ::cereal::LongitudinalPlanExt> disownLongitudinalPlanExt();
inline bool isCustomReserved2();
inline bool hasCustomReserved2();
inline ::cereal::CustomReserved2::Builder getCustomReserved2();
inline void setCustomReserved2( ::cereal::CustomReserved2::Reader value);
inline ::cereal::CustomReserved2::Builder initCustomReserved2();
inline void adoptCustomReserved2(::capnp::Orphan< ::cereal::CustomReserved2>&& value);
inline ::capnp::Orphan< ::cereal::CustomReserved2> disownCustomReserved2();
inline bool isTeToo();
inline bool hasTeToo();
inline ::cereal::TeToo::Builder getTeToo();
inline void setTeToo( ::cereal::TeToo::Reader value);
inline ::cereal::TeToo::Builder initTeToo();
inline void adoptTeToo(::capnp::Orphan< ::cereal::TeToo>&& value);
inline ::capnp::Orphan< ::cereal::TeToo> disownTeToo();
inline bool isCustomReserved3();
inline bool hasCustomReserved3();
@@ -53230,57 +53230,57 @@ inline ::capnp::Orphan< ::cereal::LongitudinalPlanExt> Event::Builder::disownLon
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline bool Event::Reader::isCustomReserved2() const {
return which() == Event::CUSTOM_RESERVED2;
inline bool Event::Reader::isTeToo() const {
return which() == Event::TE_TOO;
}
inline bool Event::Builder::isCustomReserved2() {
return which() == Event::CUSTOM_RESERVED2;
inline bool Event::Builder::isTeToo() {
return which() == Event::TE_TOO;
}
inline bool Event::Reader::hasCustomReserved2() const {
if (which() != Event::CUSTOM_RESERVED2) return false;
inline bool Event::Reader::hasTeToo() const {
if (which() != Event::TE_TOO) return false;
return !_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Event::Builder::hasCustomReserved2() {
if (which() != Event::CUSTOM_RESERVED2) return false;
inline bool Event::Builder::hasTeToo() {
if (which() != Event::TE_TOO) return false;
return !_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::cereal::CustomReserved2::Reader Event::Reader::getCustomReserved2() const {
KJ_IREQUIRE((which() == Event::CUSTOM_RESERVED2),
inline ::cereal::TeToo::Reader Event::Reader::getTeToo() const {
KJ_IREQUIRE((which() == Event::TE_TOO),
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved2>::get(_reader.getPointerField(
return ::capnp::_::PointerHelpers< ::cereal::TeToo>::get(_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::cereal::CustomReserved2::Builder Event::Builder::getCustomReserved2() {
KJ_IREQUIRE((which() == Event::CUSTOM_RESERVED2),
inline ::cereal::TeToo::Builder Event::Builder::getTeToo() {
KJ_IREQUIRE((which() == Event::TE_TOO),
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved2>::get(_builder.getPointerField(
return ::capnp::_::PointerHelpers< ::cereal::TeToo>::get(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Event::Builder::setCustomReserved2( ::cereal::CustomReserved2::Reader value) {
inline void Event::Builder::setTeToo( ::cereal::TeToo::Reader value) {
_builder.setDataField<Event::Which>(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::CUSTOM_RESERVED2);
::capnp::_::PointerHelpers< ::cereal::CustomReserved2>::set(_builder.getPointerField(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::TE_TOO);
::capnp::_::PointerHelpers< ::cereal::TeToo>::set(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline ::cereal::CustomReserved2::Builder Event::Builder::initCustomReserved2() {
inline ::cereal::TeToo::Builder Event::Builder::initTeToo() {
_builder.setDataField<Event::Which>(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::CUSTOM_RESERVED2);
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved2>::init(_builder.getPointerField(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::TE_TOO);
return ::capnp::_::PointerHelpers< ::cereal::TeToo>::init(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Event::Builder::adoptCustomReserved2(
::capnp::Orphan< ::cereal::CustomReserved2>&& value) {
inline void Event::Builder::adoptTeToo(
::capnp::Orphan< ::cereal::TeToo>&& value) {
_builder.setDataField<Event::Which>(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::CUSTOM_RESERVED2);
::capnp::_::PointerHelpers< ::cereal::CustomReserved2>::adopt(_builder.getPointerField(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::TE_TOO);
::capnp::_::PointerHelpers< ::cereal::TeToo>::adopt(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::cereal::CustomReserved2> Event::Builder::disownCustomReserved2() {
KJ_IREQUIRE((which() == Event::CUSTOM_RESERVED2),
inline ::capnp::Orphan< ::cereal::TeToo> Event::Builder::disownTeToo() {
KJ_IREQUIRE((which() == Event::TE_TOO),
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved2>::disown(_builder.getPointerField(
return ::capnp::_::PointerHelpers< ::cereal::TeToo>::disown(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
Binary file not shown.
+1 -1
View File
@@ -2351,7 +2351,7 @@ struct Event {
# *********** Custom: reserved for forks ***********
controlsStateExt @107 :Custom.ControlsStateExt;
longitudinalPlanExt @108 :Custom.LongitudinalPlanExt;
customReserved2 @109 :Custom.CustomReserved2;
teToo @109 :Custom.TeToo;
customReserved3 @110 :Custom.CustomReserved3;
customReserved4 @111 :Custom.CustomReserved4;
customReserved5 @112 :Custom.CustomReserved5;
+2 -2
View File
@@ -17,8 +17,8 @@ from cereal.services import SERVICE_LIST
NO_TRAVERSAL_LIMIT = 2**64-1
def log_from_bytes(dat: bytes) -> capnp.lib.capnp._DynamicStructReader:
with log.Event.from_bytes(dat, traversal_limit_in_words=NO_TRAVERSAL_LIMIT) as msg:
def log_from_bytes(dat: bytes, struct: capnp.lib.capnp._StructModule = log.Event) -> capnp.lib.capnp._DynamicStructReader:
with struct.from_bytes(dat, traversal_limit_in_words=NO_TRAVERSAL_LIMIT) as msg:
return msg
Binary file not shown.
+2 -1
View File
@@ -54,7 +54,7 @@ static std::map<std::string, service> services = {
{ "wideRoadEncodeIdx", {"wideRoadEncodeIdx", false, 20, 1}},
{ "wideRoadCameraState", {"wideRoadCameraState", true, 20, 20}},
{ "drivingModelData", {"drivingModelData", true, 20, 10}},
{ "modelV2", {"modelV2", true, 20, 0}},
{ "modelV2", {"modelV2", true, 20, -1}},
{ "managerState", {"managerState", true, 2, 1}},
{ "uploaderState", {"uploaderState", true, 0, 1}},
{ "navInstruction", {"navInstruction", true, 1, 10}},
@@ -80,6 +80,7 @@ static std::map<std::string, service> services = {
{ "customReservedRawData2", {"customReservedRawData2", true, 0, -1}},
{ "controlsStateExt", {"controlsStateExt", false, 100, 10}},
{ "longitudinalPlanExt", {"longitudinalPlanExt", false, 20, 5}},
{ "teToo", {"teToo", false, 5, -1}},
};
#endif
+2 -1
View File
@@ -61,7 +61,7 @@ _services: dict[str, tuple] = {
"wideRoadEncodeIdx": (False, 20., 1),
"wideRoadCameraState": (True, 20., 20),
"drivingModelData": (True, 20., 10),
"modelV2": (True, 20., 0),
"modelV2": (True, 20.),
"managerState": (True, 2., 1),
"uploaderState": (True, 0., 1),
"navInstruction": (True, 1., 10),
@@ -91,6 +91,7 @@ _services: dict[str, tuple] = {
# dp
"controlsStateExt": (False, 100., 10),
"longitudinalPlanExt": (False, 20., 5),
"teToo": (False, 5),
}
SERVICE_LIST = {name: Service(*vals) for
idx, (name, vals) in enumerate(_services.items())}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
/site/
+2 -3
View File
@@ -4,7 +4,7 @@
A supported vehicle is one that just works when you install a comma device. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified.
# 288 Supported Cars
# 287 Supported Cars
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|<a href="##"><img width=2000></a>Hardware Needed<br>&nbsp;|Video|
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
@@ -25,8 +25,7 @@ A supported vehicle is one that just works when you install a comma device. All
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Chrysler&model=Pacifica 2017-18">Buy Here</a></sub></details>||
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Chrysler&model=Pacifica 2019-20">Buy Here</a></sub></details>||
|Chrysler|Pacifica 2021-23|All|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Chrysler&model=Pacifica 2021-23">Buy Here</a></sub></details>||
|Chrysler|Pacifica Hybrid 2017|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Chrysler&model=Pacifica Hybrid 2017">Buy Here</a></sub></details>||
|Chrysler|Pacifica Hybrid 2018|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Chrysler&model=Pacifica Hybrid 2018">Buy Here</a></sub></details>||
|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Chrysler&model=Pacifica Hybrid 2017-18">Buy Here</a></sub></details>||
|Chrysler|Pacifica Hybrid 2019-24|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Chrysler&model=Pacifica Hybrid 2019-24">Buy Here</a></sub></details>||
|comma|body|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|None||
|CUPRA|Ateca 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=CUPRA&model=Ateca 2018-23">Buy Here</a></sub></details>||
-53
View File
@@ -1,53 +0,0 @@
# Minimal makefile for Sphinx documentation
#
OPENPILOT_ROOT = `git rev-parse --show-toplevel`
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
DOCSDIR = "$(OPENPILOT_ROOT)/docs"
SOURCEDIR = "$(OPENPILOT_ROOT)/build/docs"
DOCSBUILDDIR = "$(OPENPILOT_ROOT)/build/docs"
BUILDDIR = "$(OPENPILOT_ROOT)/build"
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(DOCSBUILDDIR)" $(SPHINXOPTS) $(O)
clean:
@echo "Cleaning build folder..."
rm -rf "$(BUILDDIR)"
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@echo "Cleaning build folder..."
rm -rf "$(BUILDDIR)"
mkdir -p "$(DOCSBUILDDIR)"
@echo "Copying docs & config to build folder..."
cp -a "$(DOCSDIR)" "$(BUILDDIR)"
cd "$(OPENPILOT_ROOT)" && \
find . -type f \( -name "*.md" -o -name "*.rst" -o -name "*.png" -o -name "*.jpg" -o -name "*.svg" \) \
-not -path "*/.*" \
-not -path "./build/*" \
-not -path "./docs/*" \
-not -path "./xx/*" \
-exec cp --parents "{}" ./build/docs/ \;
@echo "Building rst files..."
sphinx-apidoc -o "$(DOCSBUILDDIR)" ../ \
../xx ../rednose_repo ../notebooks ../panda_jungle \
../third_party \
../panda/examples \
../scripts \
../selfdrive/modeld \
../selfdrive/debug \
$(shell find .. -type d -name "*test* -not -path "**.venv**" \")
@echo "Building html files..."
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(DOCSBUILDDIR)" $(SPHINXOPTS) $(O)
+21 -2
View File
@@ -1,3 +1,22 @@
# openpilot-docs
# openpilot docs
These docs are autogenerated from [this folder](https://github.com/commaai/openpilot/tree/master/docs) in the main openpilot repository.
This is the source for [docs.comma.ai](https://docs.comma.ai).
The site is updated on pushes to master by this [workflow](../.github/workflows/docs.yaml).
## development
```
# install the docs dependencies
pip install .[docs]
cd docs/
# for a development server
mkdocs serve
# build the site
mkdocs build
```
References:
* https://www.mkdocs.org/getting-started/
* https://github.com/ntno/mkdocs-terminal
+1
View File
@@ -9,6 +9,7 @@ Most development happens on normal Ubuntu workstations, and not in cars or direc
```bash
# get the latest stuff
git pull
git lfs pull
git submodule update --init --recursive
# update dependencies
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

-2
View File
@@ -1,2 +0,0 @@
User-agent: *
Sitemap: https://docs.comma.ai/sitemap.xml
-87
View File
@@ -1,87 +0,0 @@
openpilot
==========
opendbc
------
.. autodoxygenindex::
:project: opendbc_can
cereal
------
messaging
^^^^^^^^^
.. autodoxygenindex::
:project: msgq_repo_msgq
visionipc
^^^^^^^^^
.. autodoxygenindex::
:project: msgq_repo_msgq_visionipc
selfdrive
---------
camerad
^^^^^^^
.. autodoxygenindex::
:project: system_camerad_cameras
locationd
^^^^^^^^^
.. autodoxygenindex::
:project: selfdrive_locationd
ui
^^
.. autodoxygenindex::
:project: selfdrive_ui
replay
""""""
.. autodoxygenindex::
:project: tools_replay
qt
""
.. autodoxygenindex::
:project: selfdrive_ui_qt_offroad
proclogd
^^^^^^^^
.. autodoxygenindex::
:project: system_proclogd
modeld
^^^^^^
.. autodoxygenindex::
:project: selfdrive_modeld_transforms
.. autodoxygenindex::
:project: selfdrive_modeld_models
.. autodoxygenindex::
:project: selfdrive_modeld_runners
common
^^^^^^
.. autodoxygenindex::
:project: common
sensorsd
^^^^^^^^
.. autodoxygenindex::
:project: system_sensord_sensors
pandad
^^^^^^
.. autodoxygenindex::
:project: selfdrive_pandad
rednose
-------
.. autodoxygenindex::
:project: rednose_repo_rednose_helpers
-147
View File
@@ -1,147 +0,0 @@
# type: ignore
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
from os.path import exists
from openpilot.common.basedir import BASEDIR
from openpilot.system.version import get_version
sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('..'))
VERSION = get_version()
# -- Project information -----------------------------------------------------
project = 'openpilot docs'
copyright = '2021, comma.ai' # noqa: A001
author = 'comma.ai'
version = VERSION
release = VERSION
language = 'en'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc', # Auto-generate docs
'sphinx.ext.viewcode', # Add view code link to modules
'sphinx_rtd_theme', # Read The Docs theme
'myst_parser', # Markdown parsing
'breathe', # Doxygen C/C++ integration
'sphinx_sitemap', # sitemap generation for SEO
]
myst_html_meta = {
"description": "openpilot docs",
"keywords": "op, openpilot, docs, documentation",
"robots": "all,follow",
"googlebot": "index,follow,snippet,archive",
"property=og:locale": "en_US",
"property=og:site_name": "docs.comma.ai",
"property=og:url": "https://docs.comma.ai",
"property=og:title": "openpilot Documentation",
"property=og:type": "website",
"property=og:image:type": "image/jpeg",
"property=og:image:width": "400",
"property=og:image": "https://docs.comma.ai/_static/logo.png",
"property=og:image:url": "https://docs.comma.ai/_static/logo.png",
"property=og:image:secure_url": "https://docs.comma.ai/_static/logo.png",
"property=og:description": "openpilot Documentation",
"property=twitter:card": "summary_large_image",
"property=twitter:logo": "https://docs.comma.ai/_static/logo.png",
"property=twitter:title": "openpilot Documentation",
"property=twitter:description": "openpilot Documentation"
}
html_baseurl = 'https://docs.comma.ai/'
sitemap_filename = "sitemap.xml"
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
# -- c docs configuration ---------------------------------------------------
# Breathe Configuration
# breathe_default_project = "c_docs"
breathe_build_directory = f"{BASEDIR}/build/docs/html/xml"
breathe_separate_member_pages = True
breathe_default_members = ('members', 'private-members', 'undoc-members')
breathe_domain_by_extension = {
"h": "cc",
}
breathe_implementation_filename_extensions = ['.c', '.cc']
breathe_doxygen_config_options = {}
breathe_projects_source = {}
# only document files that have accompanying .cc files next to them
print("searching for c_docs...")
for root, _, files in os.walk(BASEDIR):
found = False
breath_src = {}
breathe_srcs_list = []
for file in files:
ccFile = os.path.join(root, file)[:-2] + ".cc"
if file.endswith(".h") and exists(ccFile):
f = os.path.join(root, file)
parent_dir_abs = os.path.dirname(f)
parent_dir = parent_dir_abs[len(BASEDIR) + 1:]
parent_project = parent_dir.replace('/', '_')
print(f"\tFOUND: {f} in {parent_project}")
breathe_srcs_list.append(file)
found = True
if found:
breath_src[parent_project] = (parent_dir_abs, breathe_srcs_list)
breathe_projects_source.update(breath_src)
print(f"breathe_projects_source: {breathe_projects_source.keys()}")
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
html_show_copyright = True
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_logo = '_static/logo.png'
html_favicon = '_static/favicon.ico'
html_theme_options = {
'logo_only': False,
'display_version': True,
'vcs_pageview_mode': 'blob',
'style_nav_header_background': '#000000',
}
html_extra_path = ['_static']
@@ -0,0 +1,22 @@
# What is a car port?
A car port enables openpilot support on a particular car. Each car model openpilot supports needs to be individually ported. All car ports live in `openpilot/selfdrive/car/`.
The complexity of a car port varies depending on many factors including:
* existing openpilot support for similar cars
* architecture and APIs available in the car
# Structure of a car port
* `interface.py`: Interface for the car, defines the CarInterface class
* `carstate.py`: Reads CAN from car and builds openpilot CarState message
* `carcontroller.py`: Builds CAN messages to send to car
* `values.py`: Limits for actuation, general constants for cars, and supported car documentation
* `radar_interface.py`: Interface for parsing radar points from the car
# Overiew
[Jason Young](https://github.com/jyoung8607) gave a talk at COMMA_CON with an overview of the car porting process. The talk is available on YouTube:
https://youtu.be/KcfzEHB6ms4?si=5szh1PX6TksOCKmM
+1
View File
@@ -0,0 +1 @@
# Architecture
+5
View File
@@ -0,0 +1,5 @@
# Roadmap
Coming soon...
For now, check out our GitHub [milestones](https://github.com/commaai/openpilot/milestones) and [bounties](https://comma.ai/bounties).
@@ -1,6 +1,6 @@
# What is openpilot?
[openpilot](http://github.com/commaai/openpilot) is an open source driver assistance system. Currently, openpilot performs the functions of Adaptive Cruise Control (ACC), Automated Lane Centering (ALC), Forward Collision Warning (FCW), and Lane Departure Warning (LDW) for a growing variety of [supported car makes, models, and model years](docs/CARS.md). In addition, while openpilot is engaged, a camera-based Driver Monitoring (DM) feature alerts distracted and asleep drivers. See more about [the vehicle integration](docs/INTEGRATION.md) and [limitations](docs/LIMITATIONS.md).
[openpilot](http://github.com/commaai/openpilot) is an open source driver assistance system. Currently, openpilot performs the functions of Adaptive Cruise Control (ACC), Automated Lane Centering (ALC), Forward Collision Warning (FCW), and Lane Departure Warning (LDW) for a growing variety of [supported car makes, models, and model years](https://github.com/commaai/openpilot/blob/master/docs/CARS.md). In addition, while openpilot is engaged, a camera-based Driver Monitoring (DM) feature alerts distracted and asleep drivers. See more about [the vehicle integration](https://github.com/commaai/openpilot/blob/master/docs/INTEGRATION.md) and [limitations](https://github.com/commaai/openpilot/blob/master/docs/LIMITATIONS.md).
## How do I use it?
+76
View File
@@ -0,0 +1,76 @@
# connect to a comma 3/3X
A comma 3/3X is a normal [Linux](https://github.com/commaai/agnos-builder) computer that exposes [SSH](https://wiki.archlinux.org/title/Secure_Shell) and a [serial console](https://wiki.archlinux.org/title/Working_with_the_serial_console).
## Serial Console
On both the comma three and 3X, the serial console is accessible from the main OBD-C port.
Connect the comma 3/3X to your computer with a normal USB C cable, or use a [comma serial](https://comma.ai/shop/comma-serial) for steady 12V power.
On the comma three, the serial console is exposed through a UART-to-USB chip, and `tools/serial/connect.sh` can be used to connect.
On the comma 3X, the serial console is accessible through the [panda](https://github.com/commaai/panda) using the `panda/tests/som_debug.sh` script.
## SSH
In order to SSH into your device, you'll need a GitHub account with SSH keys. See this [GitHub article](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh) for getting your account setup with SSH keys.
* Enable SSH in your device's settings
* Enter your GitHub username in the device's settings
* Connect to your device
* Username: `comma`
* Port: `22`
Here's an example command for connecting to your device using its tethered connection:<br />
`ssh comma@192.168.43.1`
For doing development work on device, it's recommended to use [SSH agent forwarding](https://docs.github.com/en/developers/overview/using-ssh-agent-forwarding).
### Notes
The public keys are only fetched from your GitHub account once. In order to update your device's authorized keys, you'll need to re-enter your GitHub username.
The `id_rsa` key in this directory only works while your device is in the setup state with no software installed. After installation, that default key will be removed.
#### ssh.comma.ai proxy
With a [comma prime subscription](https://comma.ai/connect), you can SSH into your comma device from anywhere.
With the below SSH configuration, you can type `ssh comma-{dongleid}` to connect to your device through `ssh.comma.ai`.
```
Host comma-*
Port 22
User comma
IdentityFile ~/.ssh/my_github_key
ProxyCommand ssh %h@ssh.comma.ai -W %h:%p
Host ssh.comma.ai
Hostname ssh.comma.ai
Port 22
IdentityFile ~/.ssh/my_github_key
```
## One-off connection
```
ssh -i ~/.ssh/my_github_key -o ProxyCommand="ssh -i ~/.ssh/my_github_key -W %h:%p -p %p %h@ssh.comma.ai" comma@ffffffffffffffff
```
(Replace `ffffffffffffffff` with your dongle_id)
## ssh.comma.ai host key fingerprint
```
Host key fingerprint is SHA256:X22GOmfjGb9J04IA2+egtdaJ7vW9Fbtmpz9/x8/W1X4
+---[RSA 4096]----+
| |
| |
| . |
| + o |
| S = + +..|
| + @ = .=|
| . B @ ++=|
| o * B XE|
| .o o OB/|
+----[SHA256]-----+
```
View File
+1
View File
@@ -0,0 +1 @@
getting-started/what-is-openpilot.md
-42
View File
@@ -1,42 +0,0 @@
# openpilot Documentation
```{include} README.md
```
```{toctree}
:caption: 'General'
:maxdepth: 4
CARS.md
CONTRIBUTING.md
INTEGRATION.md
LIMITATIONS.md
SAFETY.md
```
```{toctree}
:caption: 'Overview'
:maxdepth: 2
overview.rst
```
## API Documentation
- {ref}`genindex`
- {ref}`modindex`
- {ref}`search`
```{toctree}
:caption: 'Python API'
:maxdepth: 2
modules.rst
```
```{toctree}
:caption: 'C/C++ API'
:maxdepth: 4
c_docs.rst
```
+32
View File
@@ -0,0 +1,32 @@
site_name: openpilot docs
docs_dir: docs
repo_url: https://github.com/commaai/openpilot/
site_url: https://docs.comma.ai
strict: true
theme:
name: terminal
features:
- navigation.side.toc.hide
nav:
- Getting Started:
- What is openpilot?: getting-started/what-is-openpilot.md
- How-to:
#- Make my first pull request: how-to/first-pr.md
- Connect to a comma 3/3X: how-to/connect-to-comma.md
- Car Porting:
- What is a car port?: car-porting/what-is-a-car-port.md
- Porting a car brand: car-porting/brand-port.md
- Porting a car model: car-porting/model-port.md
- Contributing:
- Roadmap: contributing/roadmap.md
#- Architecture: contributing/architecture.md
- Contributing: https://github.com/commaai/openpilot/blob/master/docs/CONTRIBUTING.md
- Links:
- Blog: https://blog.comma.ai
- Bounties: https://comma.ai/bounties
- GitHub: https://github.com/commaai
- Discord: https://discord.comma.ai
- X: https://x.com/comma_ai
-12
View File
@@ -1,12 +0,0 @@
This is the source for a new https://docs.comma.ai. It's not hosted anywhere yet, but it's easy to run locally.
https://www.mkdocs.org/getting-started/
```
pip install mkdocs mkdocs-terminal
mkdocs serve
```
inspiration:
* https://rerun.io/docs/
* https://docs.expo.dev/
@@ -1,9 +0,0 @@
# What is a car port?
All car ports live in `openpilot/selfdrive/car/`.
* interface.py: Interface for the car, defines the CarInterface class
* carstate.py: Reads CAN from car and builds openpilot CarState message
* carcontroller.py: Builds CAN messages to send to car
* values.py: Limits for actuation, general constants for cars, and supported car documentation
* radar_interface.py: Interface for parsing radar points from the car
-18
View File
@@ -1,18 +0,0 @@
site_name: openpilot docs
docs_dir: docs
repo_url: https://github.com/commaai/openpilot/
theme:
name: terminal
features:
- navigation.side.toc.hide
nav:
- Getting Started:
- What is openpilot?: getting-started/what-is-openpilot.md
- How-to:
- Turn the speed blue: how-to/turning-the-speed-blue.md
- Car Porting:
- What is a car port?: car-porting/what-is-a-car-port.md
- Porting a car brand: car-porting/brand-port.md
- Porting a car model: car-porting/model-port.md
-72
View File
@@ -1,72 +0,0 @@
openpilot
=========
.. toctree::
:maxdepth: 4
Debugging <selfdrive/debug/README.md>
system/loggerd/README.md
Driver Monitoring <selfdrive/monitoring/README.md>
Process Replay <selfdrive/test/process_replay/README.md>
cereal
=========
.. toctree::
:maxdepth: 4
cereal/README.md
cereal/messaging/msgq.md
models
=========
.. toctree::
:maxdepth: 4
models/README.md
opendbc
=========
.. toctree::
:maxdepth: 4
opendbc/README.md
panda
=========
.. toctree::
:maxdepth: 4
panda/README.md
panda/UPDATING.md
panda/board/README.md
panda/drivers/linux/README.md
panda/drivers/windows/README.md
rednose
=========
.. toctree::
:maxdepth: 4
rednose_repo/README.md
tools
=========
.. toctree::
:maxdepth: 4
tools/CTF.md
tools/joystick/README.md
tools/lib/README.md
tools/plotjuggler/README.md
tools/replay/README.md
tools/serial/README.md
Simulator <tools/sim/README.md>
tools/ssh/README.md
Webcam <tools/webcam/README.md>
tools/cabana/README.md
@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="7.29 80.3 111.82 101.52">
<path d="M52.1996 178.82H74.0996" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M97.7996 106.62C96.5996 104.32 94.8996 102.62 92.6996 101.32C90.5996 100.22 88.4996 99.3203 80.8996 99.3203H45.4996C37.8996 99.3203 35.7996 100.12 33.6996 101.32C31.4996 102.52 29.6996 104.32 28.5996 106.62C27.4996 108.72 26.6996 110.92 26.6996 118.72V144.02C26.6996 151.82 27.4996 153.92 28.5996 156.12C29.7996 158.42 31.4996 160.12 33.6996 161.42C35.7996 162.52 37.8996 163.42 45.4996 163.42H80.8996C88.4996 163.42 90.5996 162.62 92.6996 161.42C94.8996 160.22 96.6996 158.42 97.7996 156.12C98.8996 154.02 99.6996 151.82 99.6996 144.02V118.72C99.6996 110.82 98.8996 108.72 97.7996 106.62Z" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.3995 131.32C76.3995 138.62 69.8995 144.52 63.1995 144.52C56.4995 144.52 49.9995 138.62 49.9995 131.32C49.9995 124.02 56.4995 118.12 63.1995 118.12C69.8995 118.12 76.3995 124.02 76.3995 131.32Z" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.2996 125.92C10.2996 125.92 9.59958 104.22 20.1996 92.6202C29.5996 82.4202 39.4996 83.3202 39.4996 83.3202H62.6996" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M116.1 125.92C116.1 125.92 116.8 104.22 106.2 92.6202C96.7996 82.4202 86.8996 83.3202 86.8996 83.3202H63.6996" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -23,6 +23,7 @@
#
# Version = 2024-03-29
from common.numpy_fast import interp
from openpilot.common.params import Params
# d-e2e, from modeldata.h
TRAJECTORY_SIZE = 33
@@ -88,6 +89,7 @@ class DynamicEndtoEndController:
self._mode_prev = 'acc'
self._mode_changed = False
self._frame = 0
self._road_condition_detection = Params().get_bool('dp_long_de2e_road_condition')
self._lead_gmac = GenericMovingAverageCalculator(window_size=LEAD_WINDOW_SIZE)
self._has_lead_filtered = False
@@ -213,7 +215,7 @@ class DynamicEndtoEndController:
# when detecting slow down scenario: blended
# e.g. traffic light, curve, stop sign etc.
if self._has_slow_down:
if self._road_condition_detection and self._has_slow_down:
self._set_mode('blended')
return
@@ -261,7 +263,7 @@ class DynamicEndtoEndController:
# when detecting slow down scenario: blended
# e.g. traffic light, curve, stop sign etc.
if self._has_slow_down:
if self._road_condition_detection and self._has_slow_down:
self._set_mode('blended')
return
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,711 @@
import math
from typing import List, Dict, Tuple, Optional
from rtree import index
import numpy as np
from functools import lru_cache, cached_property
PADDING = 0.0001
LANE_WIDTH = 3.7 # meters
MIN_WAY_DIST = 500 # meters
TO_RADIANS = math.pi / 180.0
class Position:
"""
Represents a geographic position with latitude, longitude, bearing, and speed.
"""
def __init__(self, latitude: float, longitude: float, bearing: float, speed: float):
self.latitude = latitude
self.longitude = longitude
self.bearing = bearing
self.speed = speed
class Coordinates:
"""
Represents a geographic coordinate with latitude and longitude.
"""
def __init__(self, latitude: float, longitude: float):
self.latitude = latitude
self.longitude = longitude
class Way:
"""
Represents a road or path in the map.
"""
def __init__(self, id: int, nodes: List[Coordinates], name: str, ref: str, oneway: bool, lanes: int, tags: Dict[str, str]):
self.id = id
self.nodes = nodes
self.name = name
self.ref = ref
self.oneway = oneway
self.lanes = max(lanes, 2)
self.tags = tags
def get_tag(self, key: str, default: str = None) -> str:
"""
Get a tag value by its key.
Args:
key (str): The tag key to look up.
default (str, optional): The default value to return if the key is not found.
Returns:
str: The value of the tag, or the default value if not found.
"""
return self.tags.get(key, default)
@cached_property
def bounding_box(self) -> Tuple[float, float, float, float]:
"""
Calculate and cache the bounding box of the way.
Returns a tuple of (min_lat, min_lon, max_lat, max_lon).
"""
lats = [node.latitude for node in self.nodes]
lons = [node.longitude for node in self.nodes]
return (min(lats), min(lons), max(lats), max(lons))
class OnWayResult:
"""
Represents the result of checking if a position is on a way.
"""
def __init__(self, on_way: bool, distance: float, is_forward: bool):
self.on_way = on_way
self.distance = distance
self.is_forward = is_forward
class CurrentWay:
"""
Represents the current way a position is on, with additional information.
"""
def __init__(self, way: Way, distance: float, on_way: OnWayResult, start_position: Coordinates, end_position: Coordinates):
self.way = way
self.distance = distance
self.on_way = on_way
self.start_position = start_position
self.end_position = end_position
class NextWayResult:
"""
Represents a potential next way in the route.
"""
def __init__(self, way: Way, is_forward: bool, start_position: Coordinates, end_position: Coordinates):
self.way = way
self.is_forward = is_forward
self.start_position = start_position
self.end_position = end_position
class AdvancedMapMatcher:
"""
A class that performs advanced map matching using various algorithms and techniques.
"""
def __init__(self, road_data: Dict):
self.ways = self._load_ways(road_data)
self.rtree = index.Index()
self.gps_buffer: List[Position] = []
self.current_way: Optional[CurrentWay] = None
self._build_rtree()
self.way_vectors = {}
self._precompute_way_vectors()
# Hidden Markov Model (HMM) variables
self.hmm_states: List[Tuple[int, int]] = []
self.hmm_transitions: Dict[Tuple[int, int], List[Tuple[int, int]]] = {}
self.current_timestep = 0
self.current_viterbi_path: Dict[Tuple[int, int], List[Tuple[int, int]]] = {}
self.current_viterbi_prob: Dict[Tuple[int, int], float] = {}
self.initialize_hmm()
def _load_ways(self, road_data: Dict) -> List[Way]:
"""
Load ways from the provided road data.
Args:
road_data (Dict): Dictionary containing road network data.
Returns:
List[Way]: List of Way objects created from the road data.
"""
ways = []
nodes_dict = {} # To store node id to coordinates mapping
# First, create a dictionary of node id to coordinates
for element in road_data['elements']:
if element['type'] == 'node':
nodes_dict[element['id']] = Coordinates(element['lat'], element['lon'])
# Then, create Way objects
for element in road_data['elements']:
if element['type'] == 'way':
try:
nodes = [nodes_dict[node_id] for node_id in element['nodes'] if node_id in nodes_dict]
if len(nodes) < 2:
print(f"Warning: Way {element['id']} has less than 2 valid nodes. Skipping.")
continue
tags = element.get('tags', {})
way = Way(
id=element['id'],
nodes=nodes,
name=tags.get('name', ''),
ref=tags.get('ref', ''),
oneway=tags.get('oneway', 'no').lower() == 'yes',
lanes=int(tags.get('lanes', '2')),
tags=tags # Store all tags
)
ways.append(way)
except KeyError as e:
print(f"Error processing way {element['id']}: {e}")
except ValueError as e:
print(f"Error processing way {element['id']}: {e}")
return ways
def _build_rtree(self):
"""
Build an R-tree spatial index for efficient spatial queries.
"""
for idx, way in enumerate(self.ways):
# Access bounding_box as a property, not a method
self.rtree.insert(idx, way.bounding_box, obj=way)
def initialize_hmm(self):
"""
Initialize the Hidden Markov Model for map matching.
"""
self.build_hmm()
self.current_timestep = 0
self.current_viterbi_path = {}
self.current_viterbi_prob = {}
initial_prob = 1.0 / len(self.hmm_states)
for state in self.hmm_states:
self.current_viterbi_path[state] = [state]
self.current_viterbi_prob[state] = initial_prob
def build_hmm(self):
"""
Build the Hidden Markov Model states and transitions.
"""
# Create states for each segment of each way
self.hmm_states = [(way.id, i) for way in self.ways for i in range(len(way.nodes) - 1)]
# Create transitions between consecutive segments of the same way
self.hmm_transitions = {
(way.id, i): [(way.id, i + 1)] for way in self.ways for i in range(len(way.nodes) - 2)
}
# Add empty transitions for the last segment of each way
for way in self.ways:
self.hmm_transitions[(way.id, len(way.nodes) - 2)] = []
@lru_cache(maxsize=1000)
def on_way(self, way: Way, pos: Position) -> OnWayResult:
"""
Determine if a position is on a given way.
Args:
way (Way): The way to check.
pos (Position): The position to check.
Returns:
OnWayResult: An object containing whether the position is on the way,
the distance to the way, and if it's in the forward direction.
"""
if self._is_within_bounding_box(way, pos):
distance = self.distance_to_way(pos, way)
lanes = max(way.lanes, 2)
road_width_estimate = float(lanes) * LANE_WIDTH
max_dist = 5 + road_width_estimate
if distance < max_dist:
is_forward = self.is_forward(way.nodes[0], way.nodes[-1], pos.bearing)
if not is_forward and way.oneway:
return OnWayResult(False, distance, is_forward)
return OnWayResult(True, distance, is_forward)
return OnWayResult(False, float('inf'), False)
def _find_nearest_ways(self, pos: Position, k: int = 5) -> List[Way]:
"""
Find the k nearest ways to a given position using the R-tree spatial index.
Args:
pos (Position): The position to search from.
k (int): The number of nearest ways to return.
Returns:
List[Way]: A list of the k nearest ways.
"""
nearest = list(self.rtree.nearest((pos.latitude, pos.longitude, pos.latitude, pos.longitude), k))
return [self.ways[i] for i in nearest]
def _distance_to_end_of_way(self, pos: Position, way: Way, is_forward: bool) -> float:
"""
Calculate the distance from the current position to the end of the way.
Args:
pos (Position): The current position.
way (Way): The way to calculate the distance for.
is_forward (bool): Whether we're moving forward on the way.
Returns:
float: The distance to the end of the way in meters.
"""
end_node = way.nodes[-1] if is_forward else way.nodes[0]
return self.haversine_distance(
Coordinates(pos.latitude, pos.longitude),
end_node
)
def next_ways(self, pos: Position, current_way: CurrentWay, is_forward: bool) -> List[NextWayResult]:
"""
Find the next ways from the current position and way.
Args:
pos (Position): The current position.
current_way (CurrentWay): The current way.
is_forward (bool): Whether to look for ways in the forward direction.
Returns:
List[NextWayResult]: A list of potential next ways.
"""
next_ways = []
dist = 0.0
way = current_way.way
forward = is_forward
start_pos = pos
while dist < MIN_WAY_DIST:
d = self._distance_to_end_of_way(start_pos, way, forward)
if d <= 0:
break
dist += d
# Use _find_nearest_ways instead of checking all ways
nearest_ways = self._find_nearest_ways(start_pos, k=5)
nw = self._find_best_next_way(way, nearest_ways, forward)
if nw is None:
break
next_ways.append(nw)
way = nw.way
start_pos = Position(nw.start_position.latitude, nw.start_position.longitude, 0, 0)
forward = nw.is_forward
if not next_ways:
nearest_ways = self._find_nearest_ways(pos, k=5)
nw = self._find_best_next_way(current_way.way, nearest_ways, is_forward)
if nw:
next_ways.append(nw)
return next_ways
def _find_best_next_way(self, current_way: Way, candidate_ways: List[Way], is_forward: bool) -> Optional[NextWayResult]:
"""
Find the best next way from a list of candidate ways.
Args:
current_way (Way): The current way.
candidate_ways (List[Way]): List of candidate ways to choose from.
is_forward (bool): Whether to look for the next way in the forward direction.
Returns:
Optional[NextWayResult]: The best next way result, or None if no suitable way is found.
"""
match_node = current_way.nodes[-1] if is_forward else current_way.nodes[0]
match_bearing_node = current_way.nodes[-2] if is_forward else current_way.nodes[1]
# Filter candidate ways to those that connect to the current way
connecting_ways = [way for way in candidate_ways if match_node in (way.nodes[0], way.nodes[-1])]
if not connecting_ways:
return None
# First, check for ways with matching names
name_matches = [way for way in connecting_ways if way.name == current_way.name]
if name_matches:
return self._select_best_way(name_matches, match_node, match_bearing_node)
# Then, check for ways with matching references
ref_matches = [way for way in connecting_ways if way.ref == current_way.ref]
if ref_matches:
return self._select_best_way(ref_matches, match_node, match_bearing_node)
# Finally, select the way with the least curvature
return self._select_best_way(connecting_ways, match_node, match_bearing_node)
def _get_way_start_end(self, way: Way, is_forward: bool) -> Tuple[Coordinates, Coordinates]:
"""
Get the start and end coordinates of a way based on the direction of travel.
Args:
way (Way): The way to get start and end coordinates for.
is_forward (bool): Whether the way is being traversed in the forward direction.
Returns:
Tuple[Coordinates, Coordinates]: The start and end coordinates of the way.
"""
if is_forward:
return way.nodes[0], way.nodes[-1]
else:
return way.nodes[-1], way.nodes[0]
def _calculate_angle(self, p1: Coordinates, p2: Coordinates, p3: Coordinates) -> float:
"""
Calculate the angle between three points.
Args:
p1 (Coordinates): First point
p2 (Coordinates): Second point (vertex of the angle)
p3 (Coordinates): Third point
Returns:
float: Angle in radians
"""
v1 = (p1.latitude - p2.latitude, p1.longitude - p2.longitude)
v2 = (p3.latitude - p2.latitude, p3.longitude - p2.longitude)
dot_product = v1[0] * v2[0] + v1[1] * v2[1]
mag_v1 = math.sqrt(v1[0]**2 + v1[1]**2)
mag_v2 = math.sqrt(v2[0]**2 + v2[1]**2)
cos_angle = dot_product / (mag_v1 * mag_v2)
# Clamp the value to avoid domain errors due to floating point precision
cos_angle = max(-1.0, min(1.0, cos_angle))
return math.acos(cos_angle)
def _select_best_way(self, ways: List[Way], match_node: Coordinates, match_bearing_node: Coordinates) -> NextWayResult:
"""
Select the best way from a list of ways based on curvature and direction.
Args:
ways (List[Way]): List of candidate ways.
match_node (Coordinates): The node where the ways should connect.
match_bearing_node (Coordinates): The node used to calculate the bearing of the current way.
Returns:
NextWayResult: The best next way result.
"""
best_way = None
best_curvature = float('inf')
best_is_forward = False
for way in ways:
is_forward = way.nodes[0] == match_node
if not is_forward and way.oneway:
continue
bearing_node = way.nodes[1] if is_forward else way.nodes[-2]
curvature = abs(self._calculate_angle(match_bearing_node, match_node, bearing_node))
if curvature < best_curvature:
best_way = way
best_curvature = curvature
best_is_forward = is_forward
if best_way is None:
return None
start, end = self._get_way_start_end(best_way, best_is_forward)
return NextWayResult(best_way, best_is_forward, start, end)
def update_gps(self, pos: Position) -> Optional[CurrentWay]:
"""
Update the map matcher with a new GPS position.
Args:
pos (Position): The new GPS position.
Returns:
Optional[CurrentWay]: The current way if found, or None if not on any way.
"""
self.gps_buffer.append(pos)
if len(self.gps_buffer) > 25:
self.gps_buffer.pop(0)
# Check if we're still on the current way
if self.current_way and self.on_way(self.current_way.way, pos).on_way:
# Simple update if still on the same way
return self._update_current_way(pos)
# If not, find the nearest ways and check them
nearest_ways = self._find_nearest_ways(pos)
for way in nearest_ways:
on_way_result = self.on_way(way, pos)
if on_way_result.on_way:
return self._update_current_way(pos, way, on_way_result)
# Only use HMM if we can't find a clear match
if self.current_timestep % 5 == 0:
self._viterbi_step(pos)
self.current_timestep += 1
if not self.current_viterbi_prob:
return None
most_likely_state = max(self.current_viterbi_prob, key=self.current_viterbi_prob.get)
way = next((way for way in self.ways if way.id == most_likely_state[0]), None)
if way is None:
return None
on_way_result = self.on_way(way, pos)
start, end = self._get_way_start_end(way, on_way_result.is_forward)
current_way = CurrentWay(way, on_way_result.distance, on_way_result, start, end)
# Use next_ways to get upcoming ways
upcoming_ways = self.next_ways(pos, current_way, on_way_result.is_forward)
# You could store these upcoming ways for future use or return them along with the current way
self.upcoming_ways = upcoming_ways
return current_way
def _update_current_way(self, pos: Position, way: Way = None, on_way_result: OnWayResult = None) -> CurrentWay:
"""
Update the current way based on the new position.
Args:
pos (Position): The new GPS position.
way (Way, optional): The way to update to. If None, uses the current way.
on_way_result (OnWayResult, optional): The result of checking if the position is on the way.
Returns:
CurrentWay: The updated current way.
"""
if way is None:
way = self.current_way.way
if on_way_result is None:
on_way_result = self.on_way(way, pos)
start, end = self._get_way_start_end(way, on_way_result.is_forward)
current_way = CurrentWay(way, on_way_result.distance, on_way_result, start, end)
# Update upcoming ways
self.upcoming_ways = self.next_ways(pos, current_way, on_way_result.is_forward)
return current_way
def _viterbi_step(self, pos: Position):
"""
Perform a step of the Viterbi algorithm for Hidden Markov Model-based map matching.
This method updates the probabilities of being in each state (way segment) given the new position.
Args:
pos (Position): The new GPS position.
"""
new_viterbi_prob = {}
new_viterbi_path = {}
for state in self.hmm_states:
way = next((w for w in self.ways if w.id == state[0]), None)
if way is None:
continue
emission_prob = self._emission_probability(pos, way, state[1])
max_prob = float('-inf')
max_prev_state = None
for prev_state in self.hmm_transitions.get(state, []):
if prev_state in self.current_viterbi_prob:
transition_prob = self._transition_probability(prev_state, state)
# Consider upcoming ways in transition probability
if hasattr(self, 'upcoming_ways'):
upcoming_way_ids = [w.way.id for w in self.upcoming_ways]
if state[0] in upcoming_way_ids:
transition_prob *= 1.2 # Increase probability for upcoming ways
prob = self.current_viterbi_prob[prev_state] + math.log(transition_prob) + math.log(emission_prob)
if prob > max_prob:
max_prob = prob
max_prev_state = prev_state
if max_prev_state is not None:
new_viterbi_prob[state] = max_prob
new_viterbi_path[state] = self.current_viterbi_path[max_prev_state] + [state]
self.current_viterbi_prob = new_viterbi_prob
self.current_viterbi_path = new_viterbi_path
@lru_cache(maxsize=1000)
def _emission_probability(self, pos: Position, way: Way, segment_index: int) -> float:
"""
Calculate the emission probability for a given position and way segment.
This probability represents how likely it is that the GPS position would be observed
if the true position was on the given way segment.
Args:
pos (Position): The current GPS position.
way (Way): The candidate way.
segment_index (int): The index of the segment in the way.
Returns:
float: The emission probability.
"""
start_node = way.nodes[segment_index]
end_node = way.nodes[segment_index + 1]
distance = self.point_to_line_distance(pos.latitude, pos.longitude,
start_node.latitude, start_node.longitude,
end_node.latitude, end_node.longitude)
return math.exp(-distance / 20.0) # Assuming GPS error std dev of 20 meters
@lru_cache(maxsize=1000)
def _transition_probability(self, prev_state: Tuple[int, int], curr_state: Tuple[int, int]) -> float:
"""
Calculate the transition probability between two states.
Args:
prev_state (Tuple[int, int]): The previous state (way_id, segment_index).
curr_state (Tuple[int, int]): The current state (way_id, segment_index).
Returns:
float: The transition probability.
"""
prev_way = next((way for way in self.ways if way.id == prev_state[0]), None)
curr_way = next((way for way in self.ways if way.id == curr_state[0]), None)
if prev_way is None or curr_way is None:
return 0.0 # Invalid transition
if prev_state[0] == curr_state[0]: # Same way
if curr_state[1] == prev_state[1] + 1: # Next segment
return 0.95
else:
# Handle the case where the way has 3 or fewer nodes
segment_count = len(prev_way.nodes) - 1
if segment_count <= 2:
return 0.05 if curr_state[1] != prev_state[1] else 0.0
else:
return 0.05 / (segment_count - 1) # Uniform distribution over other segments
else: # Different way
return 0.05 / (len(self.ways) - 1) # Uniform distribution over other ways
@staticmethod
def _is_within_bounding_box(way: Way, pos: Position) -> bool:
"""
Check if a position is within the bounding box of a way.
Args:
way (Way): The way to check.
pos (Position): The position to check.
Returns:
bool: True if the position is within the bounding box, False otherwise.
"""
bbox = way.bounding_box
return (bbox[0] - PADDING <= pos.latitude <= bbox[2] + PADDING and
bbox[1] - PADDING <= pos.longitude <= bbox[3] + PADDING)
def _precompute_way_vectors(self):
"""
Precompute vectors for each way to speed up distance calculations.
"""
self.way_vectors = {}
for way in self.ways:
coords = np.array([(node.latitude, node.longitude) for node in way.nodes])
self.way_vectors[way.id] = coords
def distance_to_way(self, pos: Position, way: Way) -> float:
"""
Calculate the minimum distance from a position to a way.
Args:
pos (Position): The position to check.
way (Way): The way to calculate distance to.
Returns:
float: The minimum distance from the position to the way.
"""
way_vector = self.way_vectors[way.id]
pos_vector = np.array([pos.latitude, pos.longitude])
distances = np.sum((way_vector[:-1] - pos_vector)**2, axis=1)
return np.min(distances)**0.5
@staticmethod
def is_forward(start: Coordinates, end: Coordinates, bearing: float) -> bool:
"""
Determine if the bearing is in the forward direction of the way.
Args:
start (Coordinates): The start coordinates of the way.
end (Coordinates): The end coordinates of the way.
bearing (float): The bearing to check.
Returns:
bool: True if the bearing is in the forward direction, False otherwise.
"""
way_bearing = AdvancedMapMatcher.calculate_bearing(start, end)
return abs((way_bearing - bearing + 180) % 360 - 180) < 90
@staticmethod
def calculate_bearing(start: Coordinates, end: Coordinates) -> float:
"""
Calculate the bearing between two coordinates.
Args:
start (Coordinates): The start coordinates.
end (Coordinates): The end coordinates.
Returns:
float: The bearing in degrees.
"""
y = math.sin(end.longitude - start.longitude) * math.cos(end.latitude)
x = math.cos(start.latitude) * math.sin(end.latitude) - math.sin(start.latitude) * math.cos(end.latitude) * math.cos(end.longitude - start.longitude)
return (math.atan2(y, x) * 180 / math.pi + 360) % 360
@staticmethod
def haversine_distance(start: Coordinates, end: Coordinates) -> float:
"""
Calculate the Haversine distance between two coordinates.
Args:
start (Coordinates): The start coordinates.
end (Coordinates): The end coordinates.
Returns:
float: The distance in meters.
"""
R = 6371000 # Earth radius in meters
lat1, lon1 = start.latitude * TO_RADIANS, start.longitude * TO_RADIANS
lat2, lon2 = end.latitude * TO_RADIANS, end.longitude * TO_RADIANS
dlat, dlon = lat2 - lat1, lon2 - lon1
a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
return R * c
@staticmethod
def point_to_line_distance(px: float, py: float, x1: float, y1: float, x2: float, y2: float) -> float:
"""
Calculate the perpendicular distance from a point to a line segment.
Args:
px (float): X-coordinate of the point.
py (float): Y-coordinate of the point.
x1 (float): X-coordinate of the first point of the line segment.
y1 (float): Y-coordinate of the first point of the line segment.
x2 (float): X-coordinate of the second point of the line segment.
y2 (float): Y-coordinate of the second point of the line segment.
Returns:
float: The perpendicular distance from the point to the line segment.
"""
dx, dy = x2 - x1, y2 - y1
if dx == dy == 0: # The segment is actually a point
return math.sqrt((px - x1)**2 + (py - y1)**2)
t = ((px - x1) * dx + (py - y1) * dy) / (dx**2 + dy**2)
if t < 0:
return math.sqrt((px - x1)**2 + (py - y1)**2)
elif t > 1:
return math.sqrt((px - x2)**2 + (py - y2)**2)
else:
return abs((dy*px - dx*py + x2*y1 - y2*x1) / math.sqrt(dx**2 + dy**2))
+459
View File
@@ -0,0 +1,459 @@
import math
from typing import List, Dict, Tuple, Optional, Deque
from rtree import index
import logging
from functools import lru_cache
from collections import deque
from dataclasses import dataclass
import numpy as np
# Set up logging
logging.basicConfig(level=logging.WARNING, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Constants
TO_RADIANS = math.pi / 180.0
EARTH_RADIUS = 6371000 # Earth radius in meters
PADDING = 100 # meters
LANE_WIDTH = 3.7 # meters
MIN_WAY_DIST = 500 # meters
MAX_DISTANCE = 25 # meters, maximum distance to consider a way as matching
SEARCH_RADIUS = 50 # meters
class Coordinates:
__slots__ = ['lat', 'lon']
def __init__(self, lat: float, lon: float):
self.lat = lat
self.lon = lon
def __eq__(self, other):
return isinstance(other, Coordinates) and self.lat == other.lat and self.lon == other.lon
def __hash__(self):
return hash((self.lat, self.lon))
class Position:
__slots__ = ['lat', 'lon', 'bearing', 'speed', 'turn_signal']
def __init__(self, lat: float, lon: float, bearing: float, speed: float, turn_signal: Optional[str] = None):
self.lat = lat
self.lon = lon
self.bearing = bearing
self.speed = speed # Speed in meters per second
self.turn_signal = turn_signal # 'left', 'right', or None
@dataclass
class OnWayResult:
on_way: bool
distance: float
is_forward: bool
@dataclass
class CurrentWay:
way: 'Way'
distance: float
on_way: OnWayResult
start_position: Coordinates
end_position: Coordinates
confidence: float
@dataclass
class NextWayResult:
way: 'Way'
is_forward: bool
start_position: Coordinates
end_position: Coordinates
class Way:
def __init__(self, id: int, nodes: List[Coordinates], tags: Dict[str, str]):
self.id = id
self.nodes = nodes
self.tags = tags
self._bbox = self._calculate_bbox()
def _calculate_bbox(self):
lats = [node.lat for node in self.nodes]
lons = [node.lon for node in self.nodes]
return (min(lats), min(lons), max(lats), max(lons))
@property
def name(self):
# some road doesnt have name, use ID instead
return self.tags.get('name', self.id)
@property
def ref(self):
return self.tags.get('ref', '')
@property
def oneway(self):
return self.tags.get('oneway', 'no').lower() == 'yes'
@property
def lanes(self):
return int(self.tags.get('lanes', '2'))
@property
def highway_type(self):
return self.tags.get('highway', '')
@property
def is_highway(self):
highway_types = ['motorway', 'trunk', 'primary', 'secondary', 'tertiary']
return self.highway_type in highway_types
@property
def bridge(self):
return self.tags.get('bridge', 'no').lower() == 'yes'
@property
def tunnel(self):
return self.tags.get('tunnel', 'no').lower() == 'yes'
@property
def layer(self):
return int(self.tags.get('layer', '0'))
class MapMatcher:
def __init__(self, road_network: Dict):
self.ways = self._load_ways(road_network)
self.rtree = self._build_rtree()
self.current_way = None
self.position_history = deque(maxlen=10)
self.way_history = deque(maxlen=10)
self.last_switch_time = 0
self.switch_cooldown = 5 # Seconds to wait before allowing another switch
self.current_layer = 0
self.way_bearings = {} # Cache for way bearings
def _load_ways(self, road_network: Dict) -> Dict[int, Way]:
ways = {}
nodes = {}
for element in road_network['elements']:
if element['type'] == 'node':
nodes[element['id']] = Coordinates(element['lat'], element['lon'])
elif element['type'] == 'way':
way_nodes = [nodes[node_id] for node_id in element['nodes'] if node_id in nodes]
if len(way_nodes) >= 2:
ways[element['id']] = Way(element['id'], way_nodes, element.get('tags', {}))
logger.info(f"Loaded {len(ways)} ways")
return ways
def _build_rtree(self):
idx = index.Index()
for way_id, way in self.ways.items():
bbox = way._bbox
idx.insert(way_id, (bbox[1], bbox[0], bbox[3], bbox[2])) # Swap lat and lon
logger.info("R-tree index built")
return idx
def _get_nearby_ways(self, pos: Position) -> List[Way]:
lat_change = SEARCH_RADIUS / (EARTH_RADIUS * TO_RADIANS)
lon_change = SEARCH_RADIUS / (EARTH_RADIUS * TO_RADIANS * math.cos(math.radians(pos.lat)))
search_bbox = (pos.lon - lon_change, pos.lat - lat_change,
pos.lon + lon_change, pos.lat + lat_change)
nearby_way_ids = list(self.rtree.intersection(search_bbox))
return [self.ways[way_id] for way_id in nearby_way_ids]
def _get_candidate_ways(self, nearby_ways: List[Way], pos: Position) -> List[Tuple[Way, OnWayResult]]:
return [(way, self.on_way(way, pos)) for way in nearby_ways if self.on_way(way, pos).on_way]
def _select_best_match(self, candidates: List[Tuple[Way, OnWayResult]], pos: Position, timestamp: float) -> Optional[Tuple[Way, OnWayResult, float]]:
if not candidates:
return None
if len(candidates) == 1:
way, on_way_result = candidates[0]
return (way, on_way_result, self._calculate_confidence(way, on_way_result, pos))
scored_candidates = [(way, on_way_result, self._score_candidate(way, on_way_result, pos))
for way, on_way_result in candidates]
best_match = max(scored_candidates, key=lambda x: x[2])
best_way, best_on_way_result, best_score = best_match
if self._is_at_intersection(candidates):
return self._handle_intersection(scored_candidates, pos)
# Implement snapping logic
if self.current_way and self.current_way.way.id != best_way.id:
time_since_last_switch = timestamp - self.last_switch_time
if time_since_last_switch < self.switch_cooldown:
current_way_candidate = next((c for c in scored_candidates if c[0].id == self.current_way.way.id), None)
if current_way_candidate:
current_way, current_on_way_result, current_score = current_way_candidate
if current_score > best_score * 0.8: # Allow some tolerance
return (current_way, current_on_way_result, self._calculate_confidence(current_way, current_on_way_result, pos))
else:
self.last_switch_time = timestamp
return (best_way, best_on_way_result, self._calculate_confidence(best_way, best_on_way_result, pos))
def _score_candidate(self, way: Way, on_way_result: OnWayResult, pos: Position) -> float:
score = self._score_distance(on_way_result.distance)
score += self._score_continuity(way)
score += self._score_trajectory(pos)
score += self._score_speed(pos.speed)
score += self._score_historical_matches(way)
score += self._score_turn_signals(way, pos)
score += self._score_elevation(way)
score += self._score_one_way(way, on_way_result)
return score
def _score_distance(self, distance: float) -> float:
return 100 - distance
def _score_continuity(self, way: Way) -> float:
return 50 if self.current_way and way.id == self.current_way.way.id else 0
def _score_trajectory(self, pos: Position) -> float:
if len(self.position_history) < 2:
return 0
prev_pos = self.position_history[-1]
expected_bearing = self._calculate_bearing(
Coordinates(prev_pos.lat, prev_pos.lon),
Coordinates(pos.lat, pos.lon)
)
bearing_diff = abs(expected_bearing - pos.bearing)
return -min(bearing_diff, 360 - bearing_diff)
def _score_speed(self, speed: float) -> float:
return 20 if speed > 8.33 else (-20 if speed < 1.39 else 0)
def _score_historical_matches(self, way: Way) -> float:
return 30 if way in self.way_history else 0
def _score_turn_signals(self, way: Way, pos: Position) -> float:
if not pos.turn_signal or not way.is_highway:
return 0
if self.current_way:
parallel_score = self._score_parallel_ways(self.current_way.way, way)
if parallel_score > 0:
return 40
way_bearing = self._calculate_bearing(way.nodes[0], way.nodes[-1])
return 20 if (pos.turn_signal == 'left' and way_bearing < pos.bearing) or \
(pos.turn_signal == 'right' and way_bearing > pos.bearing) else 0
def _score_elevation(self, way: Way) -> float:
if not self.current_way:
return 0
score = 0
if way.layer != self.current_layer:
score -= 50
if way.bridge != self.current_way.way.bridge:
score -= 30
if way.tunnel != self.current_way.way.tunnel:
score -= 30
return score
def _score_one_way(self, way: Way, on_way_result: OnWayResult) -> float:
return -100 if way.oneway and not on_way_result.is_forward else 0
def _is_at_intersection(self, candidates: List[Tuple[Way, OnWayResult]]) -> bool:
return len(candidates) > 2
def _handle_intersection(self, scored_candidates: List[Tuple[Way, OnWayResult, float]], pos: Position) -> Tuple[Way, OnWayResult, float]:
# Implement more sophisticated intersection handling logic here
# For now, we'll just return the highest scored candidate
return max(scored_candidates, key=lambda x: x[2])
def _calculate_confidence(self, way: Way, on_way_result: OnWayResult, pos: Position) -> float:
# Implement a confidence calculation based on various factors
# This is a simple example; you might want to develop a more sophisticated model
base_confidence = 1.0 - (on_way_result.distance / MAX_DISTANCE)
trajectory_confidence = 1.0 if len(self.position_history) < 2 else \
1.0 - min(abs(self._calculate_bearing(self.position_history[-1], pos) - pos.bearing) / 180.0, 1.0)
return (base_confidence + trajectory_confidence) / 2
def update_position(self, pos: Position, timestamp: float) -> Optional[CurrentWay]:
logger.debug(f"Updating position: lat={pos.lat}, lon={pos.lon}, bearing={pos.bearing}, speed={pos.speed}, turn_signal={pos.turn_signal}")
nearby_ways = self._get_nearby_ways(pos)
candidate_ways = self._get_candidate_ways(nearby_ways, pos)
best_match = self._select_best_match(candidate_ways, pos, timestamp)
if best_match:
way, on_way_result, confidence = best_match
logger.info(f"Matched to way: {way.id} with confidence {confidence:.2f}")
self.position_history.append(pos)
self.way_history.append(way)
return self._update_current_way(pos, way, on_way_result, confidence)
logger.warning("No matching way found")
self.current_way = None
return None
def on_way(self, way: Way, pos: Position) -> OnWayResult:
distance = self._distance_to_way(pos.lat, pos.lon, way.id)
max_dist = 5 + way.lanes * LANE_WIDTH
if distance < max_dist:
is_forward = self._is_forward(way.id, pos.bearing)
if not is_forward and way.oneway:
return OnWayResult(False, distance, is_forward)
return OnWayResult(True, distance, is_forward)
return OnWayResult(False, distance, False)
@lru_cache(maxsize=1024)
def _distance_to_way(self, pos_lat: float, pos_lon: float, way_id: int) -> float:
way = self.ways[way_id]
return np.min([self._point_to_line_distance(pos_lat, pos_lon, start.lat, start.lon, end.lat, end.lon)
for start, end in zip(way.nodes, way.nodes[1:])])
@staticmethod
@lru_cache(maxsize=1024)
def _point_to_line_distance(px, py, x1, y1, x2, y2):
px, py, x1, y1, x2, y2 = map(math.radians, [px, py, x1, y1, x2, y2])
line_length = MapMatcher._haversine_distance(y1, x1, y2, x2)
if line_length == 0:
return MapMatcher._haversine_distance(py, px, y1, x1)
a = MapMatcher._haversine_distance(py, px, y1, x1)
b = MapMatcher._haversine_distance(py, px, y2, x2)
c = line_length
s = (a + b + c) / 2
area = math.sqrt(abs(s * (s-a) * (s-b) * (s-c)))
height = 2 * area / c
return height
@staticmethod
@lru_cache(maxsize=1024)
def _haversine_distance(lat1, lon1, lat2, lon2):
dlat = lat2 - lat1
dlon = lon2 - lon1
a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2
c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1-a))
return EARTH_RADIUS * c
def _is_forward(self, way_id: int, bearing: float) -> bool:
if way_id not in self.way_bearings:
way = self.ways[way_id]
self.way_bearings[way_id] = self._calculate_bearing(way.nodes[0], way.nodes[-1])
way_bearing = self.way_bearings[way_id]
bearing_diff = abs(way_bearing - bearing)
is_forward = bearing_diff < 90 or bearing_diff > 270
logger.debug(f"Way {way_id}: bearing {way_bearing}, vehicle bearing {bearing}, is_forward: {is_forward}")
return is_forward
@staticmethod
@lru_cache(maxsize=1024)
def _calculate_bearing(start: Coordinates, end: Coordinates) -> float:
y = np.sin(np.radians(end.lon - start.lon)) * np.cos(np.radians(end.lat))
x = np.cos(np.radians(start.lat)) * np.sin(np.radians(end.lat)) - \
np.sin(np.radians(start.lat)) * np.cos(np.radians(end.lat)) * np.cos(np.radians(end.lon - start.lon))
bearing = np.arctan2(y, x)
return (np.degrees(bearing) + 360) % 360
def _update_current_way(self, pos: Position, way: Way, on_way: OnWayResult, confidence: float) -> CurrentWay:
start, end = self._get_way_start_end(way, on_way.is_forward)
self.current_layer = way.layer
return CurrentWay(way, on_way.distance, on_way, start, end, confidence)
@staticmethod
def _get_way_start_end(way: Way, is_forward: bool) -> Tuple[Coordinates, Coordinates]:
return (way.nodes[0], way.nodes[-1]) if is_forward else (way.nodes[-1], way.nodes[0])
def next_ways(self, pos: Position, current_way: CurrentWay, is_forward: bool) -> List[NextWayResult]:
next_ways = []
dist = 0.0
way = current_way.way
forward = is_forward
start_pos = pos
while dist < MIN_WAY_DIST:
d = self._distance_to_end_of_way(start_pos, way, forward)
if d <= 0:
break
dist += d
nw = self._next_way(way, forward)
if nw is None:
break
next_ways.append(nw)
way = nw.way
start_pos = Position(nw.start_position.lat, nw.start_position.lon, 0, 0)
forward = nw.is_forward
if not next_ways:
nw = self._next_way(current_way.way, is_forward)
if nw:
next_ways.append(nw)
return next_ways
def _distance_to_end_of_way(self, pos: Position, way: Way, is_forward: bool) -> float:
nodes = way.nodes if is_forward else list(reversed(way.nodes))
return np.sum([self._haversine_distance(prev.lat, prev.lon, curr.lat, curr.lon)
for prev, curr in zip(nodes, nodes[1:])])
def _next_way(self, way: Way, is_forward: bool) -> Optional[NextWayResult]:
match_node = way.nodes[-1] if is_forward else way.nodes[0]
matching_ways = self._matching_ways(way, match_node)
if not matching_ways:
return None
for mway in matching_ways:
if mway.name == way.name or mway.ref == way.ref:
next_is_forward = self._next_is_forward(mway, match_node)
if not next_is_forward and mway.oneway:
continue
start, end = self._get_way_start_end(mway, next_is_forward)
return NextWayResult(mway, next_is_forward, start, end)
min_curv_way = min(matching_ways, key=lambda w: self._get_curvature(way, w, match_node))
next_is_forward = self._next_is_forward(min_curv_way, match_node)
start, end = self._get_way_start_end(min_curv_way, next_is_forward)
return NextWayResult(min_curv_way, next_is_forward, start, end)
def _matching_ways(self, current_way: Way, match_node: Coordinates) -> List[Way]:
return [way for way in self.ways.values()
if way.id != current_way.id and
(way.nodes[0] == match_node or way.nodes[-1] == match_node)]
@staticmethod
def _next_is_forward(next_way: Way, match_node: Coordinates) -> bool:
return next_way.nodes[0] == match_node
@staticmethod
def _get_curvature(way1: Way, way2: Way, match_node: Coordinates) -> float:
if len(way1.nodes) < 2 or len(way2.nodes) < 2:
return float('inf')
node1 = way1.nodes[-2] if way1.nodes[-1] == match_node else way1.nodes[-1]
node2 = way2.nodes[1] if way2.nodes[0] == match_node else way2.nodes[-2]
angle1 = MapMatcher._calculate_bearing(node1, match_node)
angle2 = MapMatcher._calculate_bearing(match_node, node2)
return abs(angle2 - angle1)
def _score_parallel_ways(self, current_way: Way, candidate_way: Way) -> float:
if len(current_way.nodes) < 2 or len(candidate_way.nodes) < 2:
return 0
current_bearing = self._calculate_bearing(current_way.nodes[0], current_way.nodes[-1])
candidate_bearing = self._calculate_bearing(candidate_way.nodes[0], candidate_way.nodes[-1])
bearing_diff = abs(current_bearing - candidate_bearing)
if bearing_diff > 20 and bearing_diff < 340: # Not parallel
return 0
min_distance = np.min([self._point_to_line_distance(node.lat, node.lon,
candidate_way.nodes[0].lat, candidate_way.nodes[0].lon,
candidate_way.nodes[-1].lat, candidate_way.nodes[-1].lon)
for node in current_way.nodes])
return 30 if 5 < min_distance < 20 else 0 # Boost score for potential lane change
@staticmethod
def _bbox_intersects(bbox1, bbox2):
return not (bbox1[2] < bbox2[0] or bbox1[0] > bbox2[2] or
bbox1[3] < bbox2[1] or bbox1[1] > bbox2[3])
@@ -0,0 +1,39 @@
import requests
import numpy as np
from openpilot.dp_ext.selfdrive.tetood.lib.utils import R
class OverpassAPIHelper:
def __init__(self):
self.url = 'https://overpass-api.de/api/interpreter'
# self.url = 'https://overpass.kumi.systems/api/interpreter'
self.headers = {'Accept-Encoding': 'gzip'}
def fetch_data(self, lat, lon, radius=3500, high_speed=True):
"""Fetch data from Overpass API based on the given GPS coordinates."""
bbox_angle = np.degrees(radius / R)
# fetch all ways and nodes on this ways in bbox
bbox_str = f'{str(lat - bbox_angle)},{str(lon - bbox_angle)},{str(lat + bbox_angle)},{str(lon + bbox_angle)}'
excl_way_types = 'pedestrian|footway|path|corridor|bridleway|steps|cycleway|construction|bus_guideway|escape|track'
overpass_query = f"""
[out:json][timeout:25][bbox:{bbox_str}];
(
way[highway][highway!~"^({excl_way_types})$"];
) -> .allways;
(
way[highway][highway!~"^({excl_way_types}|motorway_link)$"][!name];
) -> .no_name_ways;
(
way[highway][highway!~"^({excl_way_types})$"][service][service~"^(driveway)$"];
) -> .service_ways;
(.allways; - .no_name_ways;) -> .way_result_1;
(.way_result_1; - .service_ways;) -> .way_result_final;
(.way_result_final;>;);
out body;
"""
# print(overpass_query)
try:
response = requests.get(self.url, params={'data': overpass_query}, headers=self.headers)
except:
return None
return response.json()
@@ -0,0 +1,167 @@
import math
import json
from typing import List, Tuple, Dict, Optional
from rtree import index
class Node:
def __init__(self, id: int, lat: float, lon: float, tags: Dict = None):
self.id = id
self.lat = lat
self.lon = lon
self.tags = tags or {}
class Way:
def __init__(self, id: int, nodes: List[Node]):
self.id = id
self.nodes = nodes
class MapMatcher:
def __init__(self, prefetched_data: Dict):
# self.road_network = road_network
# self.spatial_index = self._build_spatial_index()
nodes, ways = self.parse_overpass_data(prefetched_data)
self.nodes = {node.id: node for node in nodes}
self.ways = ways
self.way_dict = {way.id: way for way in ways}
self.rtree = self._build_rtree()
def _build_rtree(self):
p = index.Property()
p.dimension = 2
rtree = index.Index(properties=p)
for i, way in enumerate(self.ways):
for node in way.nodes:
rtree.insert(i, (node.lon, node.lat, node.lon, node.lat), obj=(way.id, node.id))
return rtree
def _distance(self, lat1: float, lon1: float, lat2: float, lon2: float) -> float:
R = 6371 # Earth's radius in kilometers
lat1, lon1, lat2, lon2 = map(math.radians, [lat1, lon1, lat2, lon2])
dlat = lat2 - lat1
dlon = lon2 - lon1
a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2
c = 2 * math.asin(math.sqrt(a))
return R * c
def _find_closest_way_and_node(self, lat: float, lon: float) -> Tuple[int, int, float]:
nearest = list(self.rtree.nearest((lon, lat, lon, lat), 1, objects=True))[0]
way_id, node_id = nearest.object
node = self.nodes[node_id]
distance = self._distance(lat, lon, node.lat, node.lon)
print(f"{way_id}, {node_id}, {distance}")
return way_id, node_id, distance
def _get_nearby_ways(self, lat: float, lon: float, radius: float) -> List[int]:
# Convert radius from km to degrees (approximate)
radius_deg = radius / 111.32 # 1 degree is approximately 111.32 km
bbox = (lon - radius_deg, lat - radius_deg, lon + radius_deg, lat + radius_deg)
return list(set(item.object[0] for item in self.rtree.intersection(bbox, objects=True)))
def match(self, lat: float, lon: float, current_way: Optional[List[float]] = None, max_drift: float = 0.1) -> Tuple[int, int]:
nearby_ways = self._get_nearby_ways(lat, lon, max_drift * 2)
if current_way is None or current_way not in nearby_ways:
return self._find_closest_way_and_node(lat, lon)
else:
min_distance = float('inf')
best_way = current_way
best_node = None
for way_id in nearby_ways:
way = self.way_dict[way_id]
for node in way.nodes:
distance = self._distance(lat, lon, node.lat, node.lon)
if distance < min_distance:
min_distance = distance
best_way = way_id
best_node = node.id
return best_way, best_node, min_distance
def parse_overpass_data(self, data: str) -> Tuple[List[Node], List[Way]]:
# json_data = json.loads(data)
nodes = []
ways = []
node_dict = {}
for element in data['elements']:
if element['type'] == 'node':
node = Node(element['id'], element['lat'], element['lon'], element.get('tags'))
nodes.append(node)
node_dict[node.id] = node
elif element['type'] == 'way':
way_nodes = [node_dict[node_id] for node_id in element['nodes'] if node_id in node_dict]
way = Way(element['id'], way_nodes)
ways.append(way)
return nodes, ways
#
# # Example usage
# if __name__ == "__main__":
# overpass_data = '''
# [
# {
# "type": "node",
# "id": 775379692,
# "lat": 25.0804406,
# "lon": 121.6071380
# },
# {
# "type": "node",
# "id": 775379741,
# "lat": 25.0680739,
# "lon": 121.6170474
# },
# {
# "type": "node",
# "id": 775379747,
# "lat": 25.0733561,
# "lon": 121.6058384,
# "tags": {
# "addr:city": "台北市",
# "addr:country": "TW",
# "addr:district": "內湖區",
# "addr:housenumber": "16",
# "addr:postcode": "11486",
# "addr:street": "康寧路三段",
# "highway": "traffic_signals"
# }
# },
# {
# "type": "node",
# "id": 775379748,
# "lat": 25.0731973,
# "lon": 121.6061928,
# "tags": {
# "highway": "traffic_signals"
# }
# }
# ]
# '''
#
# nodes, ways = parse_overpass_data(overpass_data)
#
# # For this example, we'll create a dummy way using all the nodes
# dummy_way = Way(1, nodes)
# ways.append(dummy_way)
#
# map_matcher = MapMatcher(nodes, ways)
#
# # Test the map matching
# current_way = None
# current_node = None
# test_positions = [
# (25.0804406, 121.6071380),
# (25.0733561, 121.6058384),
# (25.0731973, 121.6061928),
# (25.0680739, 121.6170474)
# ]
#
# for lat, lon in test_positions:
# matched_way, matched_node = map_matcher.match(lat, lon, current_way)
# print(f"Current position: {lat}, {lon}")
# print(f"Matched way: {matched_way}, Matched node: {matched_node}")
# current_way = matched_way
# current_node = matched_node
# print("---")
@@ -0,0 +1,41 @@
import csv
import json
from typing import Dict
class SpeedCameraLoader:
def __init__(self, data_source: str = None, data_type: str = 'osm_json'):
self.data_source = data_source
self.data_type = data_type
def load_speed_cameras(self, prefetched_data: Dict = None) -> Dict[int, Dict[str, any]]:
if self.data_type == 'csv':
return self._load_from_csv()
elif self.data_type == 'osm_json':
return self._load_from_osm_json(prefetched_data)
else:
raise ValueError(f"Unsupported data type: {self.data_type}")
def _load_from_csv(self) -> Dict[int, Dict[str, any]]:
speed_cameras = {}
with open(self.data_source, 'r') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
camera_id = int(row['id'])
speed_cameras[camera_id] = {
'lat': float(row['latitude']),
'lon': float(row['longitude']),
'tags': json.loads(row.get('tags', '{}'))
}
return speed_cameras
def _load_from_osm_json(self, prefetched_data: Dict) -> Dict[int, Dict[str, any]]:
speed_cameras = {}
for element in prefetched_data['elements']:
if element['type'] == 'node' and element.get('tags', {}).get('highway') == 'speed_camera':
camera_id = element['id']
speed_cameras[camera_id] = {
'lat': float(element['lat']),
'lon': float(element['lon']),
'tags': element.get('tags', {})
}
return speed_cameras
@@ -0,0 +1,30 @@
from openpilot.dp_ext.selfdrive.tetood.lib.speed_camera_loader import SpeedCameraLoader
from typing import Dict
from openpilot.common.basedir import BASEDIR
import os
import csv
class TaiwanSpeedCameraLoader(SpeedCameraLoader):
def __init__(self, data_source: str = None, data_type: str = 'osm_json'):
self.data_source = os.path.join(BASEDIR, "dp_ext", "selfdrive", "tetood", "assets", "taiwan_speed_camera_2024_06_07.csv")
self.data_type = "csv"
self.speed_cameras = {}
def _load_from_csv(self) -> Dict[int, Dict[str, any]]:
if not self.speed_cameras:
with open(self.data_source, 'r') as csvfile:
reader = csv.DictReader(csvfile)
next(reader)
i = 0
for row in reader:
camera_id = int(f"101{i}")
place = row['Address']
self.speed_cameras[camera_id] = {
'lat': float(row['Latitude']),
'lon': float(row['Longitude']),
'tags': {"place": place, "maxspeed": float(row['limit'])},
}
i += 1
return self.speed_cameras
+67
View File
@@ -0,0 +1,67 @@
from typing import Tuple
import math
R = 6371000 # Earth's radius in meters
def haversine_distance(point1: Tuple[float, float], point2: Tuple[float, float]) -> float:
lat1, lon1 = math.radians(point1[0]), math.radians(point1[1])
lat2, lon2 = math.radians(point2[0]), math.radians(point2[1])
dlat, dlon = lat2 - lat1, lon2 - lon1
a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
return R * c
def calculate_bearing(point1: Tuple[float, float], point2: Tuple[float, float]) -> float:
"""Calculate bearing of two points"""
lat1, lon1 = math.radians(point1[0]), math.radians(point1[1])
lat2, lon2 = math.radians(point2[0]), math.radians(point2[1])
dlon = lon2 - lon1
y = math.sin(dlon) * math.cos(lat2)
x = math.cos(lat1) * math.sin(lat2) - math.sin(lat1) * math.cos(lat2) * math.cos(dlon)
initial_bearing = math.atan2(y, x)
# Convert to degrees
initial_bearing = math.degrees(initial_bearing)
bearing = (initial_bearing + 360) % 360
return bearing
def angle_diff(bearing1: float, bearing2 :float) -> float:
# Calculate the absolute angle difference
return abs((bearing1 - bearing2 + 180) % 360 - 180)
def feature_is_ahead(current_bearing: float, bearing_to_feature: float, within_deg: float = 15.):
# Consider features within a 60-degree cone in front of the vehicle
return angle_diff(current_bearing, bearing_to_feature) <= within_deg
def calculate_predicted_position(point: Tuple[float, float], bearing: float, distance: float) -> Tuple[float, float]:
# Convert bearing to radians
bearing_rad = math.radians(bearing)
# Convert lat and lon from degrees to radians
lat_rad = math.radians(point[0])
lon_rad = math.radians(point[1])
# Calculate the new latitude
new_lat_rad = math.asin(math.sin(lat_rad) * math.cos(distance / R) +
math.cos(lat_rad) * math.sin(distance / R) * math.cos(bearing_rad))
# Calculate the new longitude
new_lon_rad = lon_rad + math.atan2(math.sin(bearing_rad) * math.sin(distance / R) * math.cos(lat_rad),
math.cos(distance / R) - math.sin(lat_rad) * math.sin(new_lat_rad))
# Convert the new latitude and longitude from radians to degrees
new_lat = math.degrees(new_lat_rad)
new_lon = math.degrees(new_lon_rad)
return new_lat, new_lon
def point_to_line_distance(px, py, x1, y1, x2, y2):
numerator = abs((y2-y1)*px - (x2-x1)*py + x2*y1 - y2*x1)
denominator = ((y2-y1)**2 + (x2-x1)**2)**0.5
return numerator / denominator if denominator != 0 else float('inf')
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
ARCHNAME=$(uname -m)
if [ -f /TICI ]; then
ARCHNAME="larch64"
fi
if [[ "$OSTYPE" == "darwin"* ]]; then
ARCHNAME="Darwin"
fi
LIB_DIR=$DIR/../../../third_party/libspatialindex/$ARCHNAME/lib/
export LD_LIBRARY_PATH=$LIB_DIR:$LD_LIBRARY_PATH
exec "$DIR/tetood.py" "$@"
+403
View File
@@ -0,0 +1,403 @@
#!/usr/bin/env python3
from typing import List, Tuple, Dict
import rtree
import math
import json
import threading
from collections import deque
import time
import cereal.messaging as messaging
from cereal import log, custom
from openpilot.common.params import Params
from openpilot.common.realtime import Ratekeeper
from openpilot.common.conversions import Conversions as CV
from openpilot.system.hardware import PC
from openpilot.dp_ext.selfdrive.tetood.lib.map_matcher import MapMatcher, Position
from openpilot.dp_ext.selfdrive.tetood.lib.overpass_api_helper import OverpassAPIHelper
from openpilot.dp_ext.selfdrive.tetood.lib.taiwan_speed_camera_loader import TaiwanSpeedCameraLoader
from openpilot.dp_ext.selfdrive.tetood.lib.utils import calculate_bearing, haversine_distance, feature_is_ahead
RADIUS = 3500
FREQ = 5 # hz
DEBUG = True
class TeToo:
def __init__(self):
self.current_position = None
self.current_bearing = None
self.road_network = {}
self.traffic_signals = {}
self.index = rtree.index.Index()
self.map_matcher = None
self.overpass_helper = None
self.current_way = None
self.current_road_name = None
self.current_max_speed = 0
self.current_tags = {}
self.params = Params()
self.fetching_thread = None
self.data_lock = threading.Lock()
self.v_ego = 0.
self.v_cruise = 0.
self.cruise_enabled = False
self.gps_history = deque(maxlen=1*FREQ)
self.bearing_history = deque(maxlen=1*FREQ)
self._osm = True if PC else self.params.get_bool("dp_tetoo")
self._taiwan_speed_camera_enabled = True if PC else self.params.get_bool("dp_tetoo_speed_camera_taiwan")
self._speed_camera_threshold = int(self.params.get_bool("dp_tetoo_speed_camera_threshold")) * 0.01
self.osm_speed_cameras = {}
self.tw_speed_cameras = {}
if self._taiwan_speed_camera_enabled:
self.tw_speed_camera_loader = TaiwanSpeedCameraLoader()
self.tw_speed_cameras = self.tw_speed_camera_loader.load_speed_cameras()
if not self._osm:
self._build_road_network()
self.prefetched_data = None
self.last_fetch_position = None
if self._osm:
last_data = self.params.get("dp_tetoo_data")
if last_data is not None and last_data != "":
self.prefetched_data = json.loads(last_data)
self.map_matcher = MapMatcher(self.prefetched_data)
self._build_road_network()
last_pos = self.params.get("dp_tetoo_gps")
if last_pos is not None and last_pos != "":
self.last_fetch_position = json.loads(last_pos)
def update_position(self): #, lat: float, lon: float):
self._check_and_fetch_data()
self._map_match()
return self._get_road_info()
def _check_and_fetch_data(self):
if self._osm and not self.last_fetch_position or haversine_distance(self.current_position, self.last_fetch_position) > RADIUS - self._boundary_offset():
self._fetch_data()
def _boundary_offset(self):
"""reduce boundary at high speed"""
return 300 if self.v_ego < 16.67 else 600
def _fetch_data(self):
def fetch():
overpass_helper = OverpassAPIHelper()
self.prefetched_data = overpass_helper.fetch_data(self.current_position[0], self.current_position[1], RADIUS, self.v_ego > 23)
if self.prefetched_data is not None:
self._build_road_network()
self.last_fetch_position = self.current_position
self.params.put_nonblocking("dp_tetoo_gps", json.dumps(self.last_fetch_position))
self.params.put_nonblocking("dp_tetoo_data", json.dumps(self.prefetched_data, ensure_ascii=False))
with self.data_lock:
self.map_matcher = MapMatcher(self.prefetched_data)
if self.fetching_thread is not None and self.fetching_thread.is_alive():
return
self.fetching_thread = threading.Thread(target=fetch)
self.fetching_thread.start()
def _build_road_network(self):
new_road_network = {}
new_index = rtree.index.Index()
self.traffic_signals = {}
self.osm_speed_cameras = {}
if self._osm and self.prefetched_data:
for element in self.prefetched_data['elements']:
if element['type'] == 'way':
way_id = element['id']
new_road_network[way_id] = {
'nodes': element['nodes'],
'tags': element.get('tags', {})
}
elif element['type'] == 'node':
node_id = element['id']
lat, lon = element['lat'], element['lon']
new_index.insert(node_id, (lon, lat, lon, lat))
new_road_network[node_id] = {'lat': lat, 'lon': lon}
tags = element.get('tags', {})
if tags.get('highway') == 'traffic_signals':
self.traffic_signals[node_id] = {'lat': lat, 'lon': lon, 'tags': tags}
elif 'highway' in tags and tags['highway'] == 'speed_camera':
self.osm_speed_cameras[node_id] = {'lat': lat, 'lon': lon, 'tags': tags}
elif 'enforcement' in tags and tags['enforcement'] == 'maxspeed':
self.osm_speed_cameras[node_id] = {'lat': lat, 'lon': lon, 'tags': tags}
# Add traffic signals to the index
for node_id, node_data in self.traffic_signals.items():
new_index.insert(node_id, (node_data['lon'], node_data['lat'], node_data['lon'], node_data['lat']))
# Add OSM speed cameras to the index
for camera_id, camera_data in self.osm_speed_cameras.items():
new_index.insert(camera_id, (camera_data['lon'], camera_data['lat'], camera_data['lon'], camera_data['lat']))
# Add Taiwan speed cameras to the index
if self._taiwan_speed_camera_enabled:
for camera_id, camera_data in self.tw_speed_cameras.items():
new_index.insert(camera_id, (camera_data['lon'], camera_data['lat'], camera_data['lon'], camera_data['lat']))
with self.data_lock:
self.road_network = new_road_network
self.index = new_index
def _map_match(self):
if len(self.gps_history) < 1*FREQ:
return
if self.map_matcher is None:
return
self.current_way = self.map_matcher.update_position(Position(
lat=self.current_position[0],
lon=self.current_position[1],
bearing=self.current_position[2],
speed=self.current_position[3],
turn_signal=self.current_position[4],
), time.time())
def _get_road_info(self):
if self.current_way is None:
return {
'id': None,
'name': self.current_road_name,
'maxspeed': self.current_max_speed,
'tags': self.current_tags,
'confidence': 0.0
}
way_id = self.current_way.way.id
new_road_name = self.current_way.way.name
new_tags = self.current_way.way.tags
new_max_speed = self.current_way.way.tags.get("maxspeed", '0')
# Only update if the new name is different
if new_road_name and new_road_name != self.current_road_name:
self.current_road_name = new_road_name
self.current_max_speed = new_max_speed
self.current_tags = new_tags
return {
'id': way_id,
'name': self.current_road_name,
'maxspeed': self.current_max_speed,
'tags': self.current_tags,
# 'confidence': self.current_way_confidence
}
def _check_feature_ahead(self, feature_type: str, max_distance: float, max_distance_in_parallel: float) -> Tuple[bool, float, Dict, str]:
if self.current_position is None or self.current_bearing is None:
return False, float('inf'), {}, ""
current_lat, current_lon, current_bearing, current_speed, current_turn_signal = self.current_position
closest_feature_distance = float('inf')
closest_feature_info = {}
closest_feature_id = ""
# Define a bounding box for the spatial query
search_distance = max_distance / 111000 # Convert meters to degrees (approximate)
bbox = (
current_lon - search_distance,
current_lat - search_distance,
current_lon + search_distance,
current_lat + search_distance
)
# Query the rtree index for nearby features
nearby_features = list(self.index.intersection(bbox))
for feature_id in nearby_features:
# Check if this feature is of the correct type
if feature_type == custom.TeToo.FeatureType.trafficSignal and feature_id not in self.traffic_signals:
continue
if feature_type == custom.TeToo.FeatureType.speedCamera:
if feature_id not in self.osm_speed_cameras and feature_id not in self.tw_speed_cameras:
continue
if feature_type == custom.TeToo.FeatureType.trafficSignal:
feature_data = self.traffic_signals.get(feature_id)
elif feature_type == custom.TeToo.FeatureType.speedCamera:
feature_data = self.osm_speed_cameras.get(feature_id) or self.tw_speed_cameras.get(feature_id)
if not feature_data:
continue
feature_lat, feature_lon = feature_data['lat'], feature_data['lon']
feature_point = (feature_lat, feature_lon)
distance = haversine_distance(self.current_position, feature_point)
# Skip features beyond the maximum look-ahead distance
if distance > max_distance:
continue
bearing = calculate_bearing(self.current_position, (feature_lat, feature_lon))
# Check if the feature is ahead based on bearing
if feature_is_ahead(self.current_bearing, bearing, 20.) and distance < closest_feature_distance:
closest_feature_distance = distance
closest_feature_info = feature_data
closest_feature_id = feature_id
return bool(closest_feature_info), closest_feature_distance, closest_feature_info, closest_feature_id
def check_traffic_signal_ahead(self) -> Tuple[bool, float, Dict, str]:
MAX_TRAFFIC_SIGNAL_DISTANCE = 100 # meters
MAX_DISTANCE_IN_PARALLEL = 15
return self._check_feature_ahead(custom.TeToo.FeatureType.trafficSignal, MAX_TRAFFIC_SIGNAL_DISTANCE, MAX_DISTANCE_IN_PARALLEL)
def should_warn_speed_camera(self, distance: float, speed_limit: float, road_speed_limit: float = 0.):
# If we don't know the speed limit or we don't have a threshold set, warn anyway
if speed_limit is None or self._speed_camera_threshold == 0:
return True
speed_limit = float(speed_limit)
should_warn = False
threshold = 1 + self._speed_camera_threshold
# when we have v_cruise set
if not should_warn and self.v_cruise > 0.:
speed_limit = float(speed_limit)
lower_bound = math.floor(self.v_cruise / threshold)
upper_bound = math.ceil(self.v_cruise * threshold)
should_warn = lower_bound <= speed_limit <= upper_bound
# when the current road has a speed limit
if not should_warn and road_speed_limit > 0.:
road_lower_bound = math.floor(road_speed_limit / threshold)
road_upper_bound = math.ceil(road_speed_limit * threshold)
should_warn = road_lower_bound <= speed_limit <= road_upper_bound
# use current speed
if not should_warn:
v_ego_kph = self.v_ego * CV.MS_TO_KPH
v_lower_bound = math.floor(v_ego_kph / threshold)
v_upper_bound = math.ceil(v_ego_kph * threshold)
should_warn = v_lower_bound <= speed_limit <= v_upper_bound
return should_warn
def check_speed_camera_ahead(self) -> Tuple[bool, float, Dict, str]:
MAX_SPEED_CAMERA_DISTANCE = 1000 # meters
MAX_DISTANCE_IN_PARALLEL = 30
ahead, distance, info, id = self._check_feature_ahead(custom.TeToo.FeatureType.speedCamera, MAX_SPEED_CAMERA_DISTANCE, MAX_DISTANCE_IN_PARALLEL)
if ahead:
maxspeed = info.get('tags', {}).get('maxspeed')
if maxspeed:
info['maxspeed'] = maxspeed
return ahead, distance, info, id
def _get_feature(self, type, func, display_tags=False):
ahead, distance, info, id = func()
if not ahead:
return {}
feature = {
'id': str(id),
'type': type,
'lat': float(info['lat']),
'lon': float(info['lon']),
'distance': float(distance),
}
if display_tags:
feature['tags'] = json.dumps(info['tags'], ensure_ascii=False)
return feature
def tetoo_thread(self):
sm = messaging.SubMaster(['liveLocationKalman', 'carState', 'controlsState'])
pm = messaging.PubMaster(['teToo'])
te_too_dat_prev = {}
rk = Ratekeeper(FREQ)
lat = 0.
lon = 0.
bearing = 0.
while True:
sm.update()
location = sm['liveLocationKalman']
localizer_valid = (location.status == log.LiveLocationKalman.Status.valid) and location.positionGeodetic.valid
# Update GPS and bearing history at 20 Hz
if localizer_valid:
lat = location.positionGeodetic.value[0]
lon = location.positionGeodetic.value[1]
bearing = math.degrees(location.calibratedOrientationNED.value[2])
self.v_ego = sm['carState'].vEgo
self.cruise_enabled = sm['carState'].cruiseState.enabled
# Update vCruise
self.v_cruise = sm['controlsState'].vCruise
# Update GPS history
if self.v_ego >= 2.6:
self.gps_history.append((lat, lon, bearing, self.v_ego))
self.bearing_history.append(bearing)
use_prev = not localizer_valid or (localizer_valid and self.v_ego < 2.6)
dat = messaging.new_message('teToo', valid=True)
if use_prev:
dat.teToo = te_too_dat_prev
else:
dat.teToo.lat = float(lat)
dat.teToo.lon = float(lon)
dat.teToo.bearing = float(bearing)
road_maxspeed = 0.
blinker_state = 'left' if sm['carState'].leftBlinker else 'right' if sm['carState'].rightBlinker else None
self.current_position = (lat, lon, bearing, self.v_ego, blinker_state)
self.current_bearing = bearing
if self._osm:
road_info = self.update_position() #(lat, lon)
dat.teToo.name = str("" if road_info['name'] is None else road_info['name'])
dat.teToo.maxspeed = float(road_info['maxspeed'])
road_maxspeed = dat.teToo.maxspeed
features = []
# disable for now
# if self._osm:
# traffic_signal_ahead = self._get_feature(custom.TeToo.FeatureType.trafficSignal, self.check_traffic_signal_ahead)
# if traffic_signal_ahead:
# features.append(traffic_signal_ahead)
speed_camera_ahead = self._get_feature(custom.TeToo.FeatureType.speedCamera, self.check_speed_camera_ahead, True)
if speed_camera_ahead:
tags = speed_camera_ahead.get('tags', None)
should_show = True
if tags:
maxspeed = json.loads(tags).get('maxspeed', None)
should_show = self.should_warn_speed_camera(speed_camera_ahead['distance'], maxspeed, road_maxspeed)
if should_show:
features.append(speed_camera_ahead)
dat.teToo.nearestFeatures = features
dat.teToo.updatingData = self._osm and (self.fetching_thread is not None and self.fetching_thread.is_alive())
pm.send('teToo', dat)
te_too_dat_prev = dat.teToo
rk.keep_time()
def main():
tetoo = TeToo()
tetoo.tetoo_thread()
if __name__ == "__main__":
main()
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"/../../third_party/libspatialindex
ARCHNAME=$(uname -m)
if [ -f /TICI ]; then
ARCHNAME="larch64"
fi
if [[ "$OSTYPE" == "darwin"* ]]; then
ARCHNAME="Darwin"
fi
cd $DIR
if [ ! -d libspatialindex ]; then
git clone --single-branch https://github.com/libspatialindex/libspatialindex
fi
cd libspatialindex
# build
rm -fr build
mkdir build
cd build
cmake ..
cmake --build . -j$(nproc)
rm -fr $DIR/$ARCHNAME
mkdir -p $DIR/$ARCHNAME
make install DESTDIR=$DIR/$ARCHNAME
# clean up
rm -fr $DIR/libspatialindex/
mv $DIR/$ARCHNAME/usr/local/* $DIR/$ARCHNAME
rm -fr $DIR/$ARCHNAME/usr/
rm -fr $DIR/$ARCHNAME/lib/cmake/
rm -fr $DIR/$ARCHNAME/lib/pkgconfig/
+9
View File
@@ -76,6 +76,15 @@ function launch {
# hardware specific init
if [ -f /AGNOS ]; then
agnos_init
# dp
if ! (LD_LIBRARY_PATH=$DIR/third_party/libspatialindex/larch64/lib/ python -c "import rtree") &> /dev/null; then
pip install "$DIR/dp_ext/selfdrive/tetood/pkgs/Rtree-1.2.0-cp311-cp311-linux_aarch64.whl"
fi
else
# dp
if ! (LD_LIBRARY_PATH=$DIR/third_party/libspatialindex/x86_64/lib/ python -c "import rtree") &> /dev/null; then
pip install "$DIR/dp_ext/selfdrive/tetood/pkgs/Rtree-1.2.0-cp312-cp312-linux_x86_64.whl"
fi
fi
# write tmux scrollback to a file
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
const uint8_t gitversion[] = "DEV-3c873995-DEBUG";
const uint8_t gitversion[] = "DEV-3a83aa9c-DEBUG";
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
DEV-3c873995-DEBUG
DEV-3a83aa9c-DEBUG
BIN
View File
Binary file not shown.
+3 -4
View File
@@ -66,9 +66,8 @@ dependencies = [
[project.optional-dependencies]
docs = [
"Jinja2",
"sphinx",
"sphinx-rtd-theme",
"sphinx-sitemap"
"mkdocs",
"mkdocs-terminal",
]
testing = [
@@ -137,7 +136,7 @@ packages = [ "." ]
[tool.pytest.ini_options]
minversion = "6.0"
addopts = "--ignore=openpilot/ --ignore=cereal/ --ignore=opendbc/ --ignore=panda/ --ignore=rednose_repo/ --ignore=tinygrad_repo/ --ignore=teleoprtc_repo/ --ignore=msgq/ -Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup"
addopts = "--ignore=openpilot/ --ignore=opendbc/ --ignore=panda/ --ignore=rednose_repo/ --ignore=tinygrad_repo/ --ignore=teleoprtc_repo/ --ignore=msgq/ -Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup"
cpp_files = "test_*"
cpp_harness = "selfdrive/test/cpp_harness.py"
python_files = "test_*.py"
+14 -29
View File
@@ -4,35 +4,6 @@ from openpilot.selfdrive.car.chrysler.values import CAR
Ecu = car.CarParams.Ecu
FW_VERSIONS = {
CAR.CHRYSLER_PACIFICA_2017_HYBRID: {
(Ecu.combinationMeter, 0x742, None): [
b'68239262AH',
b'68239262AI',
b'68239262AJ',
b'68239263AH',
b'68239263AJ',
],
(Ecu.srs, 0x744, None): [
b'68238840AH',
],
(Ecu.fwdRadar, 0x753, None): [
b'68226356AI',
],
(Ecu.eps, 0x75a, None): [
b'68288309AC',
b'68288309AD',
],
(Ecu.engine, 0x7e0, None): [
b'68277480AV ',
b'68277480AX ',
b'68277480AZ ',
],
(Ecu.hybrid, 0x7e2, None): [
b'05190175BF',
b'05190175BH',
b'05190226AK',
],
},
CAR.CHRYSLER_PACIFICA_2018: {
(Ecu.combinationMeter, 0x742, None): [
b'68227902AF',
@@ -181,26 +152,39 @@ FW_VERSIONS = {
},
CAR.CHRYSLER_PACIFICA_2018_HYBRID: {
(Ecu.combinationMeter, 0x742, None): [
b'68239262AH',
b'68239262AI',
b'68239262AJ',
b'68239263AH',
b'68239263AJ',
b'68358439AE',
b'68358439AG',
],
(Ecu.srs, 0x744, None): [
b'68238840AH',
b'68358990AC',
b'68405939AA',
],
(Ecu.fwdRadar, 0x753, None): [
b'04672758AA',
b'68226356AI',
],
(Ecu.eps, 0x75a, None): [
b'68288309AC',
b'68288309AD',
b'68525339AA',
],
(Ecu.engine, 0x7e0, None): [
b'68277480AV ',
b'68277480AX ',
b'68277480AZ ',
b'68366580AI ',
b'68366580AK ',
b'68366580AM ',
],
(Ecu.hybrid, 0x7e2, None): [
b'05190175BF',
b'05190175BH',
b'05190226AI',
b'05190226AK',
b'05190226AM',
@@ -245,6 +229,7 @@ FW_VERSIONS = {
b'68416680AE ',
b'68416680AF ',
b'68416680AG ',
b'68444228AC ',
b'68444228AD ',
b'68444228AE ',
b'68444228AF ',
+2 -2
View File
@@ -35,8 +35,8 @@ class CarInterface(CarInterfaceBase):
ret.flags |= ChryslerFlags.HIGHER_MIN_STEERING_SPEED.value
# Chrysler
if candidate in (CAR.CHRYSLER_PACIFICA_2017_HYBRID, CAR.CHRYSLER_PACIFICA_2018, CAR.CHRYSLER_PACIFICA_2018_HYBRID, \
CAR.CHRYSLER_PACIFICA_2019_HYBRID, CAR.CHRYSLER_PACIFICA_2020, CAR.DODGE_DURANGO):
if candidate in (CAR.CHRYSLER_PACIFICA_2018, CAR.CHRYSLER_PACIFICA_2018_HYBRID, CAR.CHRYSLER_PACIFICA_2019_HYBRID,
CAR.CHRYSLER_PACIFICA_2020, CAR.DODGE_DURANGO):
ret.lateralTuning.init('pid')
ret.lateralTuning.pid.kpBP, ret.lateralTuning.pid.kiBP = [[9., 20.], [9., 20.]]
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.15, 0.30], [0.03, 0.05]]
+6 -10
View File
@@ -32,34 +32,30 @@ class ChryslerCarSpecs(CarSpecs):
class CAR(Platforms):
# Chrysler
CHRYSLER_PACIFICA_2017_HYBRID = ChryslerPlatformConfig(
[ChryslerCarDocs("Chrysler Pacifica Hybrid 2017")],
ChryslerCarSpecs(mass=2242., wheelbase=3.089, steerRatio=16.2),
)
CHRYSLER_PACIFICA_2018_HYBRID = ChryslerPlatformConfig(
[ChryslerCarDocs("Chrysler Pacifica Hybrid 2018")],
CHRYSLER_PACIFICA_2017_HYBRID.specs,
[ChryslerCarDocs("Chrysler Pacifica Hybrid 2017-18")],
ChryslerCarSpecs(mass=2242., wheelbase=3.089, steerRatio=16.2),
)
CHRYSLER_PACIFICA_2019_HYBRID = ChryslerPlatformConfig(
[ChryslerCarDocs("Chrysler Pacifica Hybrid 2019-24")],
CHRYSLER_PACIFICA_2017_HYBRID.specs,
CHRYSLER_PACIFICA_2018_HYBRID.specs,
)
CHRYSLER_PACIFICA_2018 = ChryslerPlatformConfig(
[ChryslerCarDocs("Chrysler Pacifica 2017-18")],
CHRYSLER_PACIFICA_2017_HYBRID.specs,
CHRYSLER_PACIFICA_2018_HYBRID.specs,
)
CHRYSLER_PACIFICA_2020 = ChryslerPlatformConfig(
[
ChryslerCarDocs("Chrysler Pacifica 2019-20"),
ChryslerCarDocs("Chrysler Pacifica 2021-23", package="All"),
],
CHRYSLER_PACIFICA_2017_HYBRID.specs,
CHRYSLER_PACIFICA_2018_HYBRID.specs,
)
# Dodge
DODGE_DURANGO = ChryslerPlatformConfig(
[ChryslerCarDocs("Dodge Durango 2020-21")],
CHRYSLER_PACIFICA_2017_HYBRID.specs,
CHRYSLER_PACIFICA_2018_HYBRID.specs,
)
# Jeep
+2 -1
View File
@@ -130,7 +130,8 @@ MIGRATION = {
# Removal of platform_str, see https://github.com/commaai/openpilot/pull/31868/
"COMMA BODY": BODY.COMMA_BODY,
"CHRYSLER PACIFICA HYBRID 2017": CHRYSLER.CHRYSLER_PACIFICA_2017_HYBRID,
"CHRYSLER PACIFICA HYBRID 2017": CHRYSLER.CHRYSLER_PACIFICA_2018_HYBRID,
"CHRYSLER_PACIFICA_2017_HYBRID": CHRYSLER.CHRYSLER_PACIFICA_2018_HYBRID,
"CHRYSLER PACIFICA HYBRID 2018": CHRYSLER.CHRYSLER_PACIFICA_2018_HYBRID,
"CHRYSLER PACIFICA HYBRID 2019": CHRYSLER.CHRYSLER_PACIFICA_2019_HYBRID,
"CHRYSLER PACIFICA 2018": CHRYSLER.CHRYSLER_PACIFICA_2018,
+3 -3
View File
@@ -15,7 +15,7 @@ class CarState(CarStateBase):
super().__init__(CP)
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
if CP.transmissionType == TransmissionType.automatic:
self.shifter_values = can_define.dv["Gear_Shift_by_Wire_FD1"]["TrnRng_D_RqGsm"]
self.shifter_values = can_define.dv["PowertrainData_10"]["TrnRng_D_Rq"]
self.vehicle_sensors_valid = False
@@ -69,7 +69,7 @@ class CarState(CarStateBase):
# gear
if self.CP.transmissionType == TransmissionType.automatic:
gear = self.shifter_values.get(cp.vl["Gear_Shift_by_Wire_FD1"]["TrnRng_D_RqGsm"])
gear = self.shifter_values.get(cp.vl["PowertrainData_10"]["TrnRng_D_Rq"])
ret.gearShifter = self.parse_gear_shifter(gear)
elif self.CP.transmissionType == TransmissionType.manual:
ret.clutchPressed = cp.vl["Engine_Clutch_Data"]["CluPdlPos_Pc_Meas"] > 0
@@ -139,7 +139,7 @@ class CarState(CarStateBase):
if CP.transmissionType == TransmissionType.automatic:
messages += [
("Gear_Shift_by_Wire_FD1", 10),
("PowertrainData_10", 10),
]
elif CP.transmissionType == TransmissionType.manual:
messages += [
+1
View File
@@ -529,6 +529,7 @@ FW_VERSIONS = {
b'28102-5MX-A900\x00\x00',
b'28102-5MX-A910\x00\x00',
b'28102-5MX-C001\x00\x00',
b'28102-5MX-C610\x00\x00',
b'28102-5MX-C910\x00\x00',
b'28102-5MX-D001\x00\x00',
b'28102-5MX-D710\x00\x00',
+2
View File
@@ -585,6 +585,7 @@ FW_VERSIONS = {
b'\xf1\x00DL3 MDPS C 1.00 1.02 56310-L7220 4DLHC102',
],
(Ecu.fwdCamera, 0x7c4, None): [
b'\xf1\x00DL3HMFC AT KOR LHD 1.00 1.01 99210-L2000 191022',
b'\xf1\x00DL3HMFC AT KOR LHD 1.00 1.02 99210-L2000 200309',
b'\xf1\x00DL3HMFC AT KOR LHD 1.00 1.04 99210-L2000 210527',
],
@@ -595,6 +596,7 @@ FW_VERSIONS = {
b'\xf1\x00OS IEB \x02 210 \x02\x14 58520-K4000',
b'\xf1\x00OS IEB \x02 212 \x11\x13 58520-K4000',
b'\xf1\x00OS IEB \x03 210 \x02\x14 58520-K4000',
b'\xf1\x00OS IEB \x03 211 \x04\x02 58520-K4000',
b'\xf1\x00OS IEB \x03 212 \x11\x13 58520-K4000',
b'\xf1\x00OS IEB \r 105\x18\t\x18 58520-K4000',
],
+1 -1
View File
@@ -39,7 +39,7 @@ routes = [
CarTestRoute("0c94aa1e1296d7c6|2021-05-05--19-48-37", CHRYSLER.JEEP_GRAND_CHEROKEE),
CarTestRoute("91dfedae61d7bd75|2021-05-22--20-07-52", CHRYSLER.JEEP_GRAND_CHEROKEE_2019),
CarTestRoute("420a8e183f1aed48|2020-03-05--07-15-29", CHRYSLER.CHRYSLER_PACIFICA_2017_HYBRID),
CarTestRoute("420a8e183f1aed48|2020-03-05--07-15-29", CHRYSLER.CHRYSLER_PACIFICA_2018_HYBRID), # 2017
CarTestRoute("43a685a66291579b|2021-05-27--19-47-29", CHRYSLER.CHRYSLER_PACIFICA_2018),
CarTestRoute("378472f830ee7395|2021-05-28--07-38-43", CHRYSLER.CHRYSLER_PACIFICA_2018_HYBRID),
CarTestRoute("8190c7275a24557b|2020-01-29--08-33-58", CHRYSLER.CHRYSLER_PACIFICA_2019_HYBRID),
@@ -62,6 +62,7 @@ class TestCarInterfaces:
car_params = CarInterface.get_params(car_name, args['fingerprints'], args['car_fw'],
experimental_long=args['experimental_long'], docs=False)
car_params = car_params.as_reader()
car_interface = CarInterface(car_params, CarController, CarState)
assert car_params
assert car_interface
-1
View File
@@ -7,7 +7,6 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
"CHEVROLET_VOLT" = [1.5961527626411784, 1.8422651988094612, 0.1572393918005158]
"CHRYSLER_PACIFICA_2018" = [2.07140, 1.3366521181047952, 0.13776367250652022]
"CHRYSLER_PACIFICA_2020" = [1.86206, 1.509076559398423, 0.14328246159386085]
"CHRYSLER_PACIFICA_2017_HYBRID" = [1.79422, 1.06831764583744, 0.116237]
"CHRYSLER_PACIFICA_2018_HYBRID" = [2.08887, 1.2943025830995154, 0.114818]
"CHRYSLER_PACIFICA_2019_HYBRID" = [1.90120, 1.1958788168371808, 0.131520]
"GENESIS_G70" = [3.8520195946707947, 2.354697063349854, 0.06830285485626221]
+2
View File
@@ -441,6 +441,7 @@ FW_VERSIONS = {
b'\x01896630ZU8000\x00\x00\x00\x00',
b'\x01896630ZU9000\x00\x00\x00\x00',
b'\x01896630ZX4000\x00\x00\x00\x00',
b'\x01896630ZX7100\x00\x00\x00\x00',
b'\x018966312L8000\x00\x00\x00\x00',
b'\x018966312M0000\x00\x00\x00\x00',
b'\x018966312M9000\x00\x00\x00\x00',
@@ -516,6 +517,7 @@ FW_VERSIONS = {
b'\x018965B1254000\x00\x00\x00\x00',
b'\x018965B1255000\x00\x00\x00\x00',
b'\x018965B1256000\x00\x00\x00\x00',
b'\x018965B1270000\x00\x00\x00\x00',
b'8965B12361\x00\x00\x00\x00\x00\x00',
b'8965B12451\x00\x00\x00\x00\x00\x00',
b'8965B16011\x00\x00\x00\x00\x00\x00',
+1 -3
View File
@@ -72,9 +72,7 @@ class Controls:
if CI is None:
cloudlog.info("controlsd is waiting for CarParams")
with car.CarParams.from_bytes(self.params.get("CarParams", block=True)) as msg:
# TODO: this shouldn't need to be a builder
self.CP = msg.as_builder()
self.CP = messaging.log_from_bytes(self.params.get("CarParams", block=True), car.CarParams)
cloudlog.info("controlsd got CarParams")
# Uses car interface helper functions, altering state won't be considered by card for actuation

Some files were not shown because too many files have changed in this diff Show More