Compare commits
41 commits
Author | SHA1 | Date | |
---|---|---|---|
25210fd400 | |||
681e33b355 | |||
67f0a2cf7e | |||
2135cba000 | |||
2868ab0bd2 | |||
5a1734f181 | |||
f09919ca62 | |||
f3775e7d01 | |||
186bfbcf99 | |||
e20a3eb040 | |||
b3ab5841a7 | |||
a575fb009d | |||
4ef6e7448b | |||
7734c41809 | |||
07d6aa5e3e | |||
890daa9702 | |||
a68df6afab | |||
16dfabc6ba | |||
e31ccb1813 | |||
64bd6f79f5 | |||
24a5a97cfb | |||
3c5cd0b1c3 | |||
156455f363 | |||
a8d43211e9 | |||
2e557af21f | |||
8a3fdaa574 | |||
8ebfef2df4 | |||
b2245f83f6 | |||
e11ec8c5f5 | |||
b416250d47 | |||
b68bc580cc | |||
abdff38ae4 | |||
f5cfe91fcb | |||
71e9fd7d4f | |||
7b757c3c0b | |||
ff8c11eb1b | |||
841ab4f7e9 | |||
ec9e9f09ee | |||
9c1fd5f7dd | |||
e023b45118 | |||
80c83c45b9 |
27 changed files with 76410 additions and 48368 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
logdata_visualization/logs/*
|
||||
*.sync-conflict*
|
||||
*.FCStd1
|
BIN
Bobbycar_wiring/20240628_Bobbycar_wiring.pdf
Normal file
BIN
Bobbycar_wiring/20240628_Bobbycar_wiring.pdf
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
3217
cad/20240713_Tankdeckel_deckel_federplatte.step
Normal file
3217
cad/20240713_Tankdeckel_deckel_federplatte.step
Normal file
File diff suppressed because it is too large
Load diff
353
cad/20240720_lenkrad_throttle-endcap.step
Normal file
353
cad/20240720_lenkrad_throttle-endcap.step
Normal file
|
@ -0,0 +1,353 @@
|
|||
ISO-10303-21;
|
||||
HEADER;
|
||||
FILE_DESCRIPTION(('FreeCAD Model'),'2;1');
|
||||
FILE_NAME('Open CASCADE Shape Model','2024-07-20T11:24:02',('Author'),(
|
||||
''),'Open CASCADE STEP processor 7.7','FreeCAD','Unknown');
|
||||
FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
#1 = APPLICATION_PROTOCOL_DEFINITION('international standard',
|
||||
'automotive_design',2000,#2);
|
||||
#2 = APPLICATION_CONTEXT(
|
||||
'core data for automotive mechanical design processes');
|
||||
#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10);
|
||||
#4 = PRODUCT_DEFINITION_SHAPE('','',#5);
|
||||
#5 = PRODUCT_DEFINITION('design','',#6,#9);
|
||||
#6 = PRODUCT_DEFINITION_FORMATION('','',#7);
|
||||
#7 = PRODUCT('Body','Body','',(#8));
|
||||
#8 = PRODUCT_CONTEXT('',#2,'mechanical');
|
||||
#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
|
||||
#10 = ADVANCED_BREP_SHAPE_REPRESENTATION('',(#11,#15),#313);
|
||||
#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14);
|
||||
#12 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#13 = DIRECTION('',(0.,0.,1.));
|
||||
#14 = DIRECTION('',(1.,0.,-0.));
|
||||
#15 = MANIFOLD_SOLID_BREP('',#16);
|
||||
#16 = CLOSED_SHELL('',(#17,#50,#75,#95,#115,#140,#165,#185,#210,#235,
|
||||
#253,#278,#304));
|
||||
#17 = ADVANCED_FACE('',(#18),#45,.T.);
|
||||
#18 = FACE_BOUND('',#19,.F.);
|
||||
#19 = EDGE_LOOP('',(#20,#30,#37,#38));
|
||||
#20 = ORIENTED_EDGE('',*,*,#21,.T.);
|
||||
#21 = EDGE_CURVE('',#22,#24,#26,.T.);
|
||||
#22 = VERTEX_POINT('',#23);
|
||||
#23 = CARTESIAN_POINT('',(4.,2.22044604925E-15,-10.));
|
||||
#24 = VERTEX_POINT('',#25);
|
||||
#25 = CARTESIAN_POINT('',(4.,0.,0.));
|
||||
#26 = LINE('',#27,#28);
|
||||
#27 = CARTESIAN_POINT('',(4.,2.331468351713E-15,-10.5));
|
||||
#28 = VECTOR('',#29,1.);
|
||||
#29 = DIRECTION('',(0.,-2.22044604925E-16,1.));
|
||||
#30 = ORIENTED_EDGE('',*,*,#31,.F.);
|
||||
#31 = EDGE_CURVE('',#24,#24,#32,.T.);
|
||||
#32 = CIRCLE('',#33,4.);
|
||||
#33 = AXIS2_PLACEMENT_3D('',#34,#35,#36);
|
||||
#34 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#35 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#36 = DIRECTION('',(1.,0.,0.));
|
||||
#37 = ORIENTED_EDGE('',*,*,#21,.F.);
|
||||
#38 = ORIENTED_EDGE('',*,*,#39,.T.);
|
||||
#39 = EDGE_CURVE('',#22,#22,#40,.T.);
|
||||
#40 = CIRCLE('',#41,4.);
|
||||
#41 = AXIS2_PLACEMENT_3D('',#42,#43,#44);
|
||||
#42 = CARTESIAN_POINT('',(0.,2.22044604925E-15,-10.));
|
||||
#43 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#44 = DIRECTION('',(1.,0.,0.));
|
||||
#45 = CYLINDRICAL_SURFACE('',#46,4.);
|
||||
#46 = AXIS2_PLACEMENT_3D('',#47,#48,#49);
|
||||
#47 = CARTESIAN_POINT('',(0.,2.331468351713E-15,-10.5));
|
||||
#48 = DIRECTION('',(0.,-2.22044604925E-16,1.));
|
||||
#49 = DIRECTION('',(1.,0.,0.));
|
||||
#50 = ADVANCED_FACE('',(#51),#70,.T.);
|
||||
#51 = FACE_BOUND('',#52,.T.);
|
||||
#52 = EDGE_LOOP('',(#53,#61,#62,#63));
|
||||
#53 = ORIENTED_EDGE('',*,*,#54,.F.);
|
||||
#54 = EDGE_CURVE('',#22,#55,#57,.T.);
|
||||
#55 = VERTEX_POINT('',#56);
|
||||
#56 = CARTESIAN_POINT('',(3.5,2.331468351713E-15,-10.5));
|
||||
#57 = LINE('',#58,#59);
|
||||
#58 = CARTESIAN_POINT('',(4.,2.22044604925E-15,-10.));
|
||||
#59 = VECTOR('',#60,1.);
|
||||
#60 = DIRECTION('',(-0.707106781187,1.570092458684E-16,-0.707106781187)
|
||||
);
|
||||
#61 = ORIENTED_EDGE('',*,*,#39,.T.);
|
||||
#62 = ORIENTED_EDGE('',*,*,#54,.T.);
|
||||
#63 = ORIENTED_EDGE('',*,*,#64,.F.);
|
||||
#64 = EDGE_CURVE('',#55,#55,#65,.T.);
|
||||
#65 = CIRCLE('',#66,3.5);
|
||||
#66 = AXIS2_PLACEMENT_3D('',#67,#68,#69);
|
||||
#67 = CARTESIAN_POINT('',(0.,2.331468351713E-15,-10.5));
|
||||
#68 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#69 = DIRECTION('',(1.,0.,0.));
|
||||
#70 = CONICAL_SURFACE('',#71,4.,0.785398163397);
|
||||
#71 = AXIS2_PLACEMENT_3D('',#72,#73,#74);
|
||||
#72 = CARTESIAN_POINT('',(0.,2.22044604925E-15,-10.));
|
||||
#73 = DIRECTION('',(-0.,-2.22044604925E-16,1.));
|
||||
#74 = DIRECTION('',(1.,0.,0.));
|
||||
#75 = ADVANCED_FACE('',(#76,#79),#90,.T.);
|
||||
#76 = FACE_BOUND('',#77,.F.);
|
||||
#77 = EDGE_LOOP('',(#78));
|
||||
#78 = ORIENTED_EDGE('',*,*,#31,.T.);
|
||||
#79 = FACE_BOUND('',#80,.F.);
|
||||
#80 = EDGE_LOOP('',(#81));
|
||||
#81 = ORIENTED_EDGE('',*,*,#82,.F.);
|
||||
#82 = EDGE_CURVE('',#83,#83,#85,.T.);
|
||||
#83 = VERTEX_POINT('',#84);
|
||||
#84 = CARTESIAN_POINT('',(5.25,0.,0.));
|
||||
#85 = CIRCLE('',#86,5.25);
|
||||
#86 = AXIS2_PLACEMENT_3D('',#87,#88,#89);
|
||||
#87 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#88 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#89 = DIRECTION('',(1.,0.,0.));
|
||||
#90 = PLANE('',#91);
|
||||
#91 = AXIS2_PLACEMENT_3D('',#92,#93,#94);
|
||||
#92 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#93 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#94 = DIRECTION('',(1.,0.,0.));
|
||||
#95 = ADVANCED_FACE('',(#96,#99),#110,.T.);
|
||||
#96 = FACE_BOUND('',#97,.T.);
|
||||
#97 = EDGE_LOOP('',(#98));
|
||||
#98 = ORIENTED_EDGE('',*,*,#64,.T.);
|
||||
#99 = FACE_BOUND('',#100,.T.);
|
||||
#100 = EDGE_LOOP('',(#101));
|
||||
#101 = ORIENTED_EDGE('',*,*,#102,.F.);
|
||||
#102 = EDGE_CURVE('',#103,#103,#105,.T.);
|
||||
#103 = VERTEX_POINT('',#104);
|
||||
#104 = CARTESIAN_POINT('',(1.7,2.331468351713E-15,-10.5));
|
||||
#105 = CIRCLE('',#106,1.7);
|
||||
#106 = AXIS2_PLACEMENT_3D('',#107,#108,#109);
|
||||
#107 = CARTESIAN_POINT('',(0.,2.331468351713E-15,-10.5));
|
||||
#108 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#109 = DIRECTION('',(1.,0.,0.));
|
||||
#110 = PLANE('',#111);
|
||||
#111 = AXIS2_PLACEMENT_3D('',#112,#113,#114);
|
||||
#112 = CARTESIAN_POINT('',(0.,2.331468351713E-15,-10.5));
|
||||
#113 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#114 = DIRECTION('',(1.,0.,0.));
|
||||
#115 = ADVANCED_FACE('',(#116),#135,.F.);
|
||||
#116 = FACE_BOUND('',#117,.F.);
|
||||
#117 = EDGE_LOOP('',(#118,#119,#127,#134));
|
||||
#118 = ORIENTED_EDGE('',*,*,#82,.T.);
|
||||
#119 = ORIENTED_EDGE('',*,*,#120,.T.);
|
||||
#120 = EDGE_CURVE('',#83,#121,#123,.T.);
|
||||
#121 = VERTEX_POINT('',#122);
|
||||
#122 = CARTESIAN_POINT('',(5.25,6.661338147751E-16,-3.));
|
||||
#123 = LINE('',#124,#125);
|
||||
#124 = CARTESIAN_POINT('',(5.25,0.,0.));
|
||||
#125 = VECTOR('',#126,1.);
|
||||
#126 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#127 = ORIENTED_EDGE('',*,*,#128,.F.);
|
||||
#128 = EDGE_CURVE('',#121,#121,#129,.T.);
|
||||
#129 = CIRCLE('',#130,5.25);
|
||||
#130 = AXIS2_PLACEMENT_3D('',#131,#132,#133);
|
||||
#131 = CARTESIAN_POINT('',(0.,6.661338147751E-16,-3.));
|
||||
#132 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#133 = DIRECTION('',(1.,0.,0.));
|
||||
#134 = ORIENTED_EDGE('',*,*,#120,.F.);
|
||||
#135 = CYLINDRICAL_SURFACE('',#136,5.25);
|
||||
#136 = AXIS2_PLACEMENT_3D('',#137,#138,#139);
|
||||
#137 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#138 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#139 = DIRECTION('',(1.,0.,0.));
|
||||
#140 = ADVANCED_FACE('',(#141),#160,.F.);
|
||||
#141 = FACE_BOUND('',#142,.T.);
|
||||
#142 = EDGE_LOOP('',(#143,#144,#152,#159));
|
||||
#143 = ORIENTED_EDGE('',*,*,#102,.T.);
|
||||
#144 = ORIENTED_EDGE('',*,*,#145,.T.);
|
||||
#145 = EDGE_CURVE('',#103,#146,#148,.T.);
|
||||
#146 = VERTEX_POINT('',#147);
|
||||
#147 = CARTESIAN_POINT('',(1.2,2.22044604925E-15,-10.));
|
||||
#148 = LINE('',#149,#150);
|
||||
#149 = CARTESIAN_POINT('',(1.7,2.331468351713E-15,-10.5));
|
||||
#150 = VECTOR('',#151,1.);
|
||||
#151 = DIRECTION('',(-0.707106781187,-1.570092458684E-16,0.707106781187)
|
||||
);
|
||||
#152 = ORIENTED_EDGE('',*,*,#153,.F.);
|
||||
#153 = EDGE_CURVE('',#146,#146,#154,.T.);
|
||||
#154 = CIRCLE('',#155,1.2);
|
||||
#155 = AXIS2_PLACEMENT_3D('',#156,#157,#158);
|
||||
#156 = CARTESIAN_POINT('',(0.,2.22044604925E-15,-10.));
|
||||
#157 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#158 = DIRECTION('',(1.,0.,0.));
|
||||
#159 = ORIENTED_EDGE('',*,*,#145,.F.);
|
||||
#160 = CONICAL_SURFACE('',#161,1.7,0.785398163397);
|
||||
#161 = AXIS2_PLACEMENT_3D('',#162,#163,#164);
|
||||
#162 = CARTESIAN_POINT('',(0.,2.331468351713E-15,-10.5));
|
||||
#163 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#164 = DIRECTION('',(1.,0.,0.));
|
||||
#165 = ADVANCED_FACE('',(#166,#169),#180,.T.);
|
||||
#166 = FACE_BOUND('',#167,.F.);
|
||||
#167 = EDGE_LOOP('',(#168));
|
||||
#168 = ORIENTED_EDGE('',*,*,#128,.T.);
|
||||
#169 = FACE_BOUND('',#170,.F.);
|
||||
#170 = EDGE_LOOP('',(#171));
|
||||
#171 = ORIENTED_EDGE('',*,*,#172,.F.);
|
||||
#172 = EDGE_CURVE('',#173,#173,#175,.T.);
|
||||
#173 = VERTEX_POINT('',#174);
|
||||
#174 = CARTESIAN_POINT('',(5.45,6.661338147751E-16,-3.));
|
||||
#175 = CIRCLE('',#176,5.45);
|
||||
#176 = AXIS2_PLACEMENT_3D('',#177,#178,#179);
|
||||
#177 = CARTESIAN_POINT('',(0.,6.661338147751E-16,-3.));
|
||||
#178 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#179 = DIRECTION('',(1.,0.,0.));
|
||||
#180 = PLANE('',#181);
|
||||
#181 = AXIS2_PLACEMENT_3D('',#182,#183,#184);
|
||||
#182 = CARTESIAN_POINT('',(0.,6.661338147751E-16,-3.));
|
||||
#183 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#184 = DIRECTION('',(1.,0.,0.));
|
||||
#185 = ADVANCED_FACE('',(#186),#205,.F.);
|
||||
#186 = FACE_BOUND('',#187,.T.);
|
||||
#187 = EDGE_LOOP('',(#188,#189,#197,#204));
|
||||
#188 = ORIENTED_EDGE('',*,*,#153,.T.);
|
||||
#189 = ORIENTED_EDGE('',*,*,#190,.T.);
|
||||
#190 = EDGE_CURVE('',#146,#191,#193,.T.);
|
||||
#191 = VERTEX_POINT('',#192);
|
||||
#192 = CARTESIAN_POINT('',(1.2,1.443289932013E-15,-6.5));
|
||||
#193 = LINE('',#194,#195);
|
||||
#194 = CARTESIAN_POINT('',(1.2,2.22044604925E-15,-10.));
|
||||
#195 = VECTOR('',#196,1.);
|
||||
#196 = DIRECTION('',(0.,-2.22044604925E-16,1.));
|
||||
#197 = ORIENTED_EDGE('',*,*,#198,.F.);
|
||||
#198 = EDGE_CURVE('',#191,#191,#199,.T.);
|
||||
#199 = CIRCLE('',#200,1.2);
|
||||
#200 = AXIS2_PLACEMENT_3D('',#201,#202,#203);
|
||||
#201 = CARTESIAN_POINT('',(0.,1.443289932013E-15,-6.5));
|
||||
#202 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#203 = DIRECTION('',(1.,0.,0.));
|
||||
#204 = ORIENTED_EDGE('',*,*,#190,.F.);
|
||||
#205 = CYLINDRICAL_SURFACE('',#206,1.2);
|
||||
#206 = AXIS2_PLACEMENT_3D('',#207,#208,#209);
|
||||
#207 = CARTESIAN_POINT('',(0.,2.22044604925E-15,-10.));
|
||||
#208 = DIRECTION('',(0.,-2.22044604925E-16,1.));
|
||||
#209 = DIRECTION('',(1.,0.,0.));
|
||||
#210 = ADVANCED_FACE('',(#211),#230,.T.);
|
||||
#211 = FACE_BOUND('',#212,.F.);
|
||||
#212 = EDGE_LOOP('',(#213,#214,#222,#229));
|
||||
#213 = ORIENTED_EDGE('',*,*,#172,.T.);
|
||||
#214 = ORIENTED_EDGE('',*,*,#215,.T.);
|
||||
#215 = EDGE_CURVE('',#173,#216,#218,.T.);
|
||||
#216 = VERTEX_POINT('',#217);
|
||||
#217 = CARTESIAN_POINT('',(6.25,4.440892098501E-16,-2.));
|
||||
#218 = LINE('',#219,#220);
|
||||
#219 = CARTESIAN_POINT('',(5.45,6.661338147751E-16,-3.));
|
||||
#220 = VECTOR('',#221,1.);
|
||||
#221 = DIRECTION('',(0.624695047554,-1.733877062911E-16,0.780868809443)
|
||||
);
|
||||
#222 = ORIENTED_EDGE('',*,*,#223,.F.);
|
||||
#223 = EDGE_CURVE('',#216,#216,#224,.T.);
|
||||
#224 = CIRCLE('',#225,6.25);
|
||||
#225 = AXIS2_PLACEMENT_3D('',#226,#227,#228);
|
||||
#226 = CARTESIAN_POINT('',(0.,4.440892098501E-16,-2.));
|
||||
#227 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#228 = DIRECTION('',(1.,0.,0.));
|
||||
#229 = ORIENTED_EDGE('',*,*,#215,.F.);
|
||||
#230 = CONICAL_SURFACE('',#231,5.45,0.674740942224);
|
||||
#231 = AXIS2_PLACEMENT_3D('',#232,#233,#234);
|
||||
#232 = CARTESIAN_POINT('',(0.,6.661338147751E-16,-3.));
|
||||
#233 = DIRECTION('',(0.,-2.22044604925E-16,1.));
|
||||
#234 = DIRECTION('',(1.,0.,0.));
|
||||
#235 = ADVANCED_FACE('',(#236),#248,.F.);
|
||||
#236 = FACE_BOUND('',#237,.T.);
|
||||
#237 = EDGE_LOOP('',(#238,#239,#247));
|
||||
#238 = ORIENTED_EDGE('',*,*,#198,.T.);
|
||||
#239 = ORIENTED_EDGE('',*,*,#240,.T.);
|
||||
#240 = EDGE_CURVE('',#191,#241,#243,.T.);
|
||||
#241 = VERTEX_POINT('',#242);
|
||||
#242 = CARTESIAN_POINT('',(0.,1.33226762955E-15,-6.));
|
||||
#243 = LINE('',#244,#245);
|
||||
#244 = CARTESIAN_POINT('',(1.2,1.443289932013E-15,-6.5));
|
||||
#245 = VECTOR('',#246,1.);
|
||||
#246 = DIRECTION('',(-0.923076923077,-8.540177112501E-17,0.384615384615)
|
||||
);
|
||||
#247 = ORIENTED_EDGE('',*,*,#240,.F.);
|
||||
#248 = CONICAL_SURFACE('',#249,1.2,1.176005207095);
|
||||
#249 = AXIS2_PLACEMENT_3D('',#250,#251,#252);
|
||||
#250 = CARTESIAN_POINT('',(0.,1.443289932013E-15,-6.5));
|
||||
#251 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#252 = DIRECTION('',(1.,0.,0.));
|
||||
#253 = ADVANCED_FACE('',(#254),#273,.T.);
|
||||
#254 = FACE_BOUND('',#255,.F.);
|
||||
#255 = EDGE_LOOP('',(#256,#257,#265,#272));
|
||||
#256 = ORIENTED_EDGE('',*,*,#223,.T.);
|
||||
#257 = ORIENTED_EDGE('',*,*,#258,.T.);
|
||||
#258 = EDGE_CURVE('',#216,#259,#261,.T.);
|
||||
#259 = VERTEX_POINT('',#260);
|
||||
#260 = CARTESIAN_POINT('',(6.25,-1.110223024625E-16,0.5));
|
||||
#261 = LINE('',#262,#263);
|
||||
#262 = CARTESIAN_POINT('',(6.25,4.440892098501E-16,-2.));
|
||||
#263 = VECTOR('',#264,1.);
|
||||
#264 = DIRECTION('',(0.,-2.22044604925E-16,1.));
|
||||
#265 = ORIENTED_EDGE('',*,*,#266,.F.);
|
||||
#266 = EDGE_CURVE('',#259,#259,#267,.T.);
|
||||
#267 = CIRCLE('',#268,6.25);
|
||||
#268 = AXIS2_PLACEMENT_3D('',#269,#270,#271);
|
||||
#269 = CARTESIAN_POINT('',(0.,-1.110223024625E-16,0.5));
|
||||
#270 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#271 = DIRECTION('',(1.,0.,0.));
|
||||
#272 = ORIENTED_EDGE('',*,*,#258,.F.);
|
||||
#273 = CYLINDRICAL_SURFACE('',#274,6.25);
|
||||
#274 = AXIS2_PLACEMENT_3D('',#275,#276,#277);
|
||||
#275 = CARTESIAN_POINT('',(0.,4.440892098501E-16,-2.));
|
||||
#276 = DIRECTION('',(0.,-2.22044604925E-16,1.));
|
||||
#277 = DIRECTION('',(1.,0.,0.));
|
||||
#278 = ADVANCED_FACE('',(#279),#299,.T.);
|
||||
#279 = FACE_BOUND('',#280,.F.);
|
||||
#280 = EDGE_LOOP('',(#281,#282,#291,#298));
|
||||
#281 = ORIENTED_EDGE('',*,*,#266,.T.);
|
||||
#282 = ORIENTED_EDGE('',*,*,#283,.T.);
|
||||
#283 = EDGE_CURVE('',#259,#284,#286,.T.);
|
||||
#284 = VERTEX_POINT('',#285);
|
||||
#285 = CARTESIAN_POINT('',(4.75,-4.440892098501E-16,2.));
|
||||
#286 = CIRCLE('',#287,1.5);
|
||||
#287 = AXIS2_PLACEMENT_3D('',#288,#289,#290);
|
||||
#288 = CARTESIAN_POINT('',(4.75,-1.110223024625E-16,0.5));
|
||||
#289 = DIRECTION('',(0.,-1.,-2.22044604925E-16));
|
||||
#290 = DIRECTION('',(1.,0.,0.));
|
||||
#291 = ORIENTED_EDGE('',*,*,#292,.F.);
|
||||
#292 = EDGE_CURVE('',#284,#284,#293,.T.);
|
||||
#293 = CIRCLE('',#294,4.75);
|
||||
#294 = AXIS2_PLACEMENT_3D('',#295,#296,#297);
|
||||
#295 = CARTESIAN_POINT('',(0.,-4.440892098501E-16,2.));
|
||||
#296 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#297 = DIRECTION('',(1.,0.,0.));
|
||||
#298 = ORIENTED_EDGE('',*,*,#283,.F.);
|
||||
#299 = TOROIDAL_SURFACE('',#300,4.75,1.5);
|
||||
#300 = AXIS2_PLACEMENT_3D('',#301,#302,#303);
|
||||
#301 = CARTESIAN_POINT('',(0.,-1.110223024625E-16,0.5));
|
||||
#302 = DIRECTION('',(0.,-2.22044604925E-16,1.));
|
||||
#303 = DIRECTION('',(1.,0.,0.));
|
||||
#304 = ADVANCED_FACE('',(#305),#308,.F.);
|
||||
#305 = FACE_BOUND('',#306,.T.);
|
||||
#306 = EDGE_LOOP('',(#307));
|
||||
#307 = ORIENTED_EDGE('',*,*,#292,.F.);
|
||||
#308 = PLANE('',#309);
|
||||
#309 = AXIS2_PLACEMENT_3D('',#310,#311,#312);
|
||||
#310 = CARTESIAN_POINT('',(0.,-4.440892098501E-16,2.));
|
||||
#311 = DIRECTION('',(0.,2.22044604925E-16,-1.));
|
||||
#312 = DIRECTION('',(1.,0.,0.));
|
||||
#313 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3)
|
||||
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#317)) GLOBAL_UNIT_ASSIGNED_CONTEXT
|
||||
((#314,#315,#316)) REPRESENTATION_CONTEXT('Context #1',
|
||||
'3D Context with UNIT and UNCERTAINTY') );
|
||||
#314 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
|
||||
#315 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
|
||||
#316 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
|
||||
#317 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#314,
|
||||
'distance_accuracy_value','confusion accuracy');
|
||||
#318 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7));
|
||||
#319 = MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#320)
|
||||
,#313);
|
||||
#320 = STYLED_ITEM('color',(#321),#15);
|
||||
#321 = PRESENTATION_STYLE_ASSIGNMENT((#322,#328));
|
||||
#322 = SURFACE_STYLE_USAGE(.BOTH.,#323);
|
||||
#323 = SURFACE_SIDE_STYLE('',(#324));
|
||||
#324 = SURFACE_STYLE_FILL_AREA(#325);
|
||||
#325 = FILL_AREA_STYLE('',(#326));
|
||||
#326 = FILL_AREA_STYLE_COLOUR('',#327);
|
||||
#327 = COLOUR_RGB('',0.800000010877,0.800000010877,0.800000010877);
|
||||
#328 = CURVE_STYLE('',#329,POSITIVE_LENGTH_MEASURE(0.1),#330);
|
||||
#329 = DRAUGHTING_PRE_DEFINED_CURVE_FONT('continuous');
|
||||
#330 = COLOUR_RGB('',9.803921802644E-02,9.803921802644E-02,
|
||||
9.803921802644E-02);
|
||||
ENDSEC;
|
||||
END-ISO-10303-21;
|
25503
cad/20240720_lenkrad_throttle-leverclip.step
Normal file
25503
cad/20240720_lenkrad_throttle-leverclip.step
Normal file
File diff suppressed because it is too large
Load diff
BIN
cad/20240720_lenkrad_throttle.FCStd
Normal file
BIN
cad/20240720_lenkrad_throttle.FCStd
Normal file
Binary file not shown.
Binary file not shown.
618
cad/teensy40_sdcard_cover-clipbody.step
Normal file
618
cad/teensy40_sdcard_cover-clipbody.step
Normal file
|
@ -0,0 +1,618 @@
|
|||
ISO-10303-21;
|
||||
HEADER;
|
||||
FILE_DESCRIPTION(('FreeCAD Model'),'2;1');
|
||||
FILE_NAME('Open CASCADE Shape Model','2024-07-19T18:26:40',('Author'),(
|
||||
''),'Open CASCADE STEP processor 7.7','FreeCAD','Unknown');
|
||||
FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
#1 = APPLICATION_PROTOCOL_DEFINITION('international standard',
|
||||
'automotive_design',2000,#2);
|
||||
#2 = APPLICATION_CONTEXT(
|
||||
'core data for automotive mechanical design processes');
|
||||
#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10);
|
||||
#4 = PRODUCT_DEFINITION_SHAPE('','',#5);
|
||||
#5 = PRODUCT_DEFINITION('design','',#6,#9);
|
||||
#6 = PRODUCT_DEFINITION_FORMATION('','',#7);
|
||||
#7 = PRODUCT('clipbody','clipbody','',(#8));
|
||||
#8 = PRODUCT_CONTEXT('',#2,'mechanical');
|
||||
#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
|
||||
#10 = ADVANCED_BREP_SHAPE_REPRESENTATION('',(#11,#15),#567);
|
||||
#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14);
|
||||
#12 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#13 = DIRECTION('',(0.,0.,1.));
|
||||
#14 = DIRECTION('',(1.,0.,-0.));
|
||||
#15 = MANIFOLD_SOLID_BREP('',#16);
|
||||
#16 = CLOSED_SHELL('',(#17,#156,#187,#211,#236,#260,#284,#308,#333,#357,
|
||||
#381,#405,#430,#454,#478,#502,#526,#543));
|
||||
#17 = ADVANCED_FACE('',(#18),#151,.F.);
|
||||
#18 = FACE_BOUND('',#19,.F.);
|
||||
#19 = EDGE_LOOP('',(#20,#30,#38,#46,#54,#62,#70,#78,#86,#94,#102,#110,
|
||||
#119,#127,#136,#144));
|
||||
#20 = ORIENTED_EDGE('',*,*,#21,.F.);
|
||||
#21 = EDGE_CURVE('',#22,#24,#26,.T.);
|
||||
#22 = VERTEX_POINT('',#23);
|
||||
#23 = CARTESIAN_POINT('',(-3.397282455353E-15,-13.,2.3));
|
||||
#24 = VERTEX_POINT('',#25);
|
||||
#25 = CARTESIAN_POINT('',(3.774758283726E-16,4.,2.3));
|
||||
#26 = LINE('',#27,#28);
|
||||
#27 = CARTESIAN_POINT('',(-3.619327060278E-15,-14.,2.3));
|
||||
#28 = VECTOR('',#29,1.);
|
||||
#29 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#30 = ORIENTED_EDGE('',*,*,#31,.T.);
|
||||
#31 = EDGE_CURVE('',#22,#32,#34,.T.);
|
||||
#32 = VERTEX_POINT('',#33);
|
||||
#33 = CARTESIAN_POINT('',(-3.306598177652E-15,-13.35981560033,
|
||||
1.531778720403));
|
||||
#34 = LINE('',#35,#36);
|
||||
#35 = CARTESIAN_POINT('',(-1.434656898377E-15,-12.66426019411,
|
||||
3.016818456582));
|
||||
#36 = VECTOR('',#37,1.);
|
||||
#37 = DIRECTION('',(2.010812452599E-16,-0.42415539625,-0.905589421224));
|
||||
#38 = ORIENTED_EDGE('',*,*,#39,.F.);
|
||||
#39 = EDGE_CURVE('',#40,#32,#42,.T.);
|
||||
#40 = VERTEX_POINT('',#41);
|
||||
#41 = CARTESIAN_POINT('',(-2.886579864025E-15,-12.5,0.5));
|
||||
#42 = LINE('',#43,#44);
|
||||
#43 = CARTESIAN_POINT('',(-2.886579864025E-15,-12.5,0.5));
|
||||
#44 = VECTOR('',#45,1.);
|
||||
#45 = DIRECTION('',(-3.127288826259E-16,-0.640184399664,0.768221279597)
|
||||
);
|
||||
#46 = ORIENTED_EDGE('',*,*,#47,.F.);
|
||||
#47 = EDGE_CURVE('',#48,#40,#50,.T.);
|
||||
#48 = VERTEX_POINT('',#49);
|
||||
#49 = CARTESIAN_POINT('',(-2.775557561563E-15,-12.,0.5));
|
||||
#50 = LINE('',#51,#52);
|
||||
#51 = CARTESIAN_POINT('',(-2.775557561563E-15,-12.,0.5));
|
||||
#52 = VECTOR('',#53,1.);
|
||||
#53 = DIRECTION('',(-2.22044604925E-16,-1.,2.22044604925E-16));
|
||||
#54 = ORIENTED_EDGE('',*,*,#55,.F.);
|
||||
#55 = EDGE_CURVE('',#56,#48,#58,.T.);
|
||||
#56 = VERTEX_POINT('',#57);
|
||||
#57 = CARTESIAN_POINT('',(-2.997602166488E-15,-12.,1.5));
|
||||
#58 = LINE('',#59,#60);
|
||||
#59 = CARTESIAN_POINT('',(-2.997602166488E-15,-12.,1.5));
|
||||
#60 = VECTOR('',#61,1.);
|
||||
#61 = DIRECTION('',(2.22044604925E-16,-2.22044604925E-16,-1.));
|
||||
#62 = ORIENTED_EDGE('',*,*,#63,.T.);
|
||||
#63 = EDGE_CURVE('',#56,#64,#66,.T.);
|
||||
#64 = VERTEX_POINT('',#65);
|
||||
#65 = CARTESIAN_POINT('',(4.440892098501E-16,3.5,1.5));
|
||||
#66 = LINE('',#67,#68);
|
||||
#67 = CARTESIAN_POINT('',(-2.997602166488E-15,-12.,1.5));
|
||||
#68 = VECTOR('',#69,1.);
|
||||
#69 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#70 = ORIENTED_EDGE('',*,*,#71,.T.);
|
||||
#71 = EDGE_CURVE('',#64,#72,#74,.T.);
|
||||
#72 = VERTEX_POINT('',#73);
|
||||
#73 = CARTESIAN_POINT('',(7.771561172376E-16,3.5,-7.771561172376E-16));
|
||||
#74 = LINE('',#75,#76);
|
||||
#75 = CARTESIAN_POINT('',(4.440892098501E-16,3.5,1.5));
|
||||
#76 = VECTOR('',#77,1.);
|
||||
#77 = DIRECTION('',(2.22044604925E-16,-2.22044604925E-16,-1.));
|
||||
#78 = ORIENTED_EDGE('',*,*,#79,.T.);
|
||||
#79 = EDGE_CURVE('',#72,#80,#82,.T.);
|
||||
#80 = VERTEX_POINT('',#81);
|
||||
#81 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#82 = LINE('',#83,#84);
|
||||
#83 = CARTESIAN_POINT('',(7.771561172376E-16,3.5,-7.771561172376E-16));
|
||||
#84 = VECTOR('',#85,1.);
|
||||
#85 = DIRECTION('',(-2.22044604925E-16,-1.,2.22044604925E-16));
|
||||
#86 = ORIENTED_EDGE('',*,*,#87,.T.);
|
||||
#87 = EDGE_CURVE('',#80,#88,#90,.T.);
|
||||
#88 = VERTEX_POINT('',#89);
|
||||
#89 = CARTESIAN_POINT('',(3.552713678801E-16,-3.552713678801E-16,-1.6));
|
||||
#90 = LINE('',#91,#92);
|
||||
#91 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#92 = VECTOR('',#93,1.);
|
||||
#93 = DIRECTION('',(2.22044604925E-16,-2.22044604925E-16,-1.));
|
||||
#94 = ORIENTED_EDGE('',*,*,#95,.T.);
|
||||
#95 = EDGE_CURVE('',#88,#96,#98,.T.);
|
||||
#96 = VERTEX_POINT('',#97);
|
||||
#97 = CARTESIAN_POINT('',(-1.86517468137E-15,-10.,-1.6));
|
||||
#98 = LINE('',#99,#100);
|
||||
#99 = CARTESIAN_POINT('',(3.552713678801E-16,-3.552713678801E-16,-1.6));
|
||||
#100 = VECTOR('',#101,1.);
|
||||
#101 = DIRECTION('',(-2.22044604925E-16,-1.,2.22044604925E-16));
|
||||
#102 = ORIENTED_EDGE('',*,*,#103,.T.);
|
||||
#103 = EDGE_CURVE('',#96,#104,#106,.T.);
|
||||
#104 = VERTEX_POINT('',#105);
|
||||
#105 = CARTESIAN_POINT('',(-1.754152378908E-15,-10.,-2.1));
|
||||
#106 = LINE('',#107,#108);
|
||||
#107 = CARTESIAN_POINT('',(-1.86517468137E-15,-10.,-1.6));
|
||||
#108 = VECTOR('',#109,1.);
|
||||
#109 = DIRECTION('',(2.22044604925E-16,-2.22044604925E-16,-1.));
|
||||
#110 = ORIENTED_EDGE('',*,*,#111,.T.);
|
||||
#111 = EDGE_CURVE('',#104,#112,#114,.T.);
|
||||
#112 = VERTEX_POINT('',#113);
|
||||
#113 = CARTESIAN_POINT('',(-1.310063169058E-15,-9.,-3.1));
|
||||
#114 = CIRCLE('',#115,1.);
|
||||
#115 = AXIS2_PLACEMENT_3D('',#116,#117,#118);
|
||||
#116 = CARTESIAN_POINT('',(-2.98494965712E-16,-9.,-2.1));
|
||||
#117 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#118 = DIRECTION('',(-2.775557561563E-16,0.,1.));
|
||||
#119 = ORIENTED_EDGE('',*,*,#120,.T.);
|
||||
#120 = EDGE_CURVE('',#112,#121,#123,.T.);
|
||||
#121 = VERTEX_POINT('',#122);
|
||||
#122 = CARTESIAN_POINT('',(1.576516694968E-15,4.,-3.1));
|
||||
#123 = LINE('',#124,#125);
|
||||
#124 = CARTESIAN_POINT('',(-1.532107773983E-15,-10.,-3.1));
|
||||
#125 = VECTOR('',#126,1.);
|
||||
#126 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#127 = ORIENTED_EDGE('',*,*,#128,.T.);
|
||||
#128 = EDGE_CURVE('',#121,#129,#131,.T.);
|
||||
#129 = VERTEX_POINT('',#130);
|
||||
#130 = CARTESIAN_POINT('',(1.576516694968E-15,5.,-2.1));
|
||||
#131 = CIRCLE('',#132,1.);
|
||||
#132 = AXIS2_PLACEMENT_3D('',#133,#134,#135);
|
||||
#133 = CARTESIAN_POINT('',(-2.98494965712E-16,4.,-2.1));
|
||||
#134 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#135 = DIRECTION('',(-2.775557561563E-16,0.,1.));
|
||||
#136 = ORIENTED_EDGE('',*,*,#137,.T.);
|
||||
#137 = EDGE_CURVE('',#129,#138,#140,.T.);
|
||||
#138 = VERTEX_POINT('',#139);
|
||||
#139 = CARTESIAN_POINT('',(8.215650382226E-16,5.,1.3));
|
||||
#140 = LINE('',#141,#142);
|
||||
#141 = CARTESIAN_POINT('',(1.798561299893E-15,5.,-3.1));
|
||||
#142 = VECTOR('',#143,1.);
|
||||
#143 = DIRECTION('',(-2.22044604925E-16,2.22044604925E-16,1.));
|
||||
#144 = ORIENTED_EDGE('',*,*,#145,.T.);
|
||||
#145 = EDGE_CURVE('',#138,#24,#146,.T.);
|
||||
#146 = CIRCLE('',#147,1.);
|
||||
#147 = AXIS2_PLACEMENT_3D('',#148,#149,#150);
|
||||
#148 = CARTESIAN_POINT('',(-1.053446622457E-15,4.,1.3));
|
||||
#149 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#150 = DIRECTION('',(-2.775557561563E-16,0.,1.));
|
||||
#151 = PLANE('',#152);
|
||||
#152 = AXIS2_PLACEMENT_3D('',#153,#154,#155);
|
||||
#153 = CARTESIAN_POINT('',(-7.738628142252E-16,-3.444301816353,
|
||||
4.086646542781E-02));
|
||||
#154 = DIRECTION('',(1.,0.,2.22044604925E-16));
|
||||
#155 = DIRECTION('',(-2.22044604925E-16,0.,1.));
|
||||
#156 = ADVANCED_FACE('',(#157),#182,.T.);
|
||||
#157 = FACE_BOUND('',#158,.T.);
|
||||
#158 = EDGE_LOOP('',(#159,#160,#168,#176));
|
||||
#159 = ORIENTED_EDGE('',*,*,#21,.F.);
|
||||
#160 = ORIENTED_EDGE('',*,*,#161,.T.);
|
||||
#161 = EDGE_CURVE('',#22,#162,#164,.T.);
|
||||
#162 = VERTEX_POINT('',#163);
|
||||
#163 = CARTESIAN_POINT('',(12.,-13.,2.3));
|
||||
#164 = LINE('',#165,#166);
|
||||
#165 = CARTESIAN_POINT('',(-3.397282455353E-15,-13.,2.3));
|
||||
#166 = VECTOR('',#167,1.);
|
||||
#167 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#168 = ORIENTED_EDGE('',*,*,#169,.T.);
|
||||
#169 = EDGE_CURVE('',#162,#170,#172,.T.);
|
||||
#170 = VERTEX_POINT('',#171);
|
||||
#171 = CARTESIAN_POINT('',(12.,4.,2.3));
|
||||
#172 = LINE('',#173,#174);
|
||||
#173 = CARTESIAN_POINT('',(12.,-14.,2.3));
|
||||
#174 = VECTOR('',#175,1.);
|
||||
#175 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#176 = ORIENTED_EDGE('',*,*,#177,.F.);
|
||||
#177 = EDGE_CURVE('',#24,#170,#178,.T.);
|
||||
#178 = LINE('',#179,#180);
|
||||
#179 = CARTESIAN_POINT('',(3.774758283726E-16,4.,2.3));
|
||||
#180 = VECTOR('',#181,1.);
|
||||
#181 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#182 = PLANE('',#183);
|
||||
#183 = AXIS2_PLACEMENT_3D('',#184,#185,#186);
|
||||
#184 = CARTESIAN_POINT('',(-3.619327060278E-15,-14.,2.3));
|
||||
#185 = DIRECTION('',(-2.775557561563E-16,2.22044604925E-16,1.));
|
||||
#186 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#187 = ADVANCED_FACE('',(#188),#206,.T.);
|
||||
#188 = FACE_BOUND('',#189,.F.);
|
||||
#189 = EDGE_LOOP('',(#190,#191,#192,#200));
|
||||
#190 = ORIENTED_EDGE('',*,*,#31,.F.);
|
||||
#191 = ORIENTED_EDGE('',*,*,#161,.T.);
|
||||
#192 = ORIENTED_EDGE('',*,*,#193,.T.);
|
||||
#193 = EDGE_CURVE('',#162,#194,#196,.T.);
|
||||
#194 = VERTEX_POINT('',#195);
|
||||
#195 = CARTESIAN_POINT('',(12.,-13.35981560033,1.531778720403));
|
||||
#196 = LINE('',#197,#198);
|
||||
#197 = CARTESIAN_POINT('',(12.,-12.66426019411,3.016818456582));
|
||||
#198 = VECTOR('',#199,1.);
|
||||
#199 = DIRECTION('',(2.010812452599E-16,-0.42415539625,-0.905589421224)
|
||||
);
|
||||
#200 = ORIENTED_EDGE('',*,*,#201,.F.);
|
||||
#201 = EDGE_CURVE('',#32,#194,#202,.T.);
|
||||
#202 = LINE('',#203,#204);
|
||||
#203 = CARTESIAN_POINT('',(-3.263953330021E-15,-13.35981560033,
|
||||
1.531778720403));
|
||||
#204 = VECTOR('',#205,1.);
|
||||
#205 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#206 = PLANE('',#207);
|
||||
#207 = AXIS2_PLACEMENT_3D('',#208,#209,#210);
|
||||
#208 = CARTESIAN_POINT('',(-3.330617892687E-15,-13.17990780016,
|
||||
1.915889360201));
|
||||
#209 = DIRECTION('',(-2.785526547833E-16,-0.905589421224,0.42415539625)
|
||||
);
|
||||
#210 = DIRECTION('',(-1.,1.855897747597E-16,-2.604812270467E-16));
|
||||
#211 = ADVANCED_FACE('',(#212),#231,.T.);
|
||||
#212 = FACE_BOUND('',#213,.T.);
|
||||
#213 = EDGE_LOOP('',(#214,#215,#216,#225));
|
||||
#214 = ORIENTED_EDGE('',*,*,#145,.T.);
|
||||
#215 = ORIENTED_EDGE('',*,*,#177,.T.);
|
||||
#216 = ORIENTED_EDGE('',*,*,#217,.F.);
|
||||
#217 = EDGE_CURVE('',#218,#170,#220,.T.);
|
||||
#218 = VERTEX_POINT('',#219);
|
||||
#219 = CARTESIAN_POINT('',(12.,5.,1.3));
|
||||
#220 = CIRCLE('',#221,1.);
|
||||
#221 = AXIS2_PLACEMENT_3D('',#222,#223,#224);
|
||||
#222 = CARTESIAN_POINT('',(12.,4.,1.3));
|
||||
#223 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#224 = DIRECTION('',(-2.775557561563E-16,0.,1.));
|
||||
#225 = ORIENTED_EDGE('',*,*,#226,.F.);
|
||||
#226 = EDGE_CURVE('',#138,#218,#227,.T.);
|
||||
#227 = LINE('',#228,#229);
|
||||
#228 = CARTESIAN_POINT('',(8.770761894539E-16,5.,1.3));
|
||||
#229 = VECTOR('',#230,1.);
|
||||
#230 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#231 = CYLINDRICAL_SURFACE('',#232,1.);
|
||||
#232 = AXIS2_PLACEMENT_3D('',#233,#234,#235);
|
||||
#233 = CARTESIAN_POINT('',(6.550315845288E-16,4.,1.3));
|
||||
#234 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#235 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#236 = ADVANCED_FACE('',(#237),#255,.T.);
|
||||
#237 = FACE_BOUND('',#238,.T.);
|
||||
#238 = EDGE_LOOP('',(#239,#240,#248,#254));
|
||||
#239 = ORIENTED_EDGE('',*,*,#39,.F.);
|
||||
#240 = ORIENTED_EDGE('',*,*,#241,.T.);
|
||||
#241 = EDGE_CURVE('',#40,#242,#244,.T.);
|
||||
#242 = VERTEX_POINT('',#243);
|
||||
#243 = CARTESIAN_POINT('',(12.,-12.5,0.5));
|
||||
#244 = LINE('',#245,#246);
|
||||
#245 = CARTESIAN_POINT('',(-2.886579864025E-15,-12.5,0.5));
|
||||
#246 = VECTOR('',#247,1.);
|
||||
#247 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#248 = ORIENTED_EDGE('',*,*,#249,.T.);
|
||||
#249 = EDGE_CURVE('',#242,#194,#250,.T.);
|
||||
#250 = LINE('',#251,#252);
|
||||
#251 = CARTESIAN_POINT('',(12.,-12.5,0.5));
|
||||
#252 = VECTOR('',#253,1.);
|
||||
#253 = DIRECTION('',(-3.127288826259E-16,-0.640184399664,0.768221279597)
|
||||
);
|
||||
#254 = ORIENTED_EDGE('',*,*,#201,.F.);
|
||||
#255 = PLANE('',#256);
|
||||
#256 = AXIS2_PLACEMENT_3D('',#257,#258,#259);
|
||||
#257 = CARTESIAN_POINT('',(-2.886579864025E-15,-12.5,0.5));
|
||||
#258 = DIRECTION('',(7.107474605133E-18,-0.768221279597,-0.640184399664)
|
||||
);
|
||||
#259 = DIRECTION('',(-3.127288826259E-16,-0.640184399664,0.768221279597)
|
||||
);
|
||||
#260 = ADVANCED_FACE('',(#261),#279,.F.);
|
||||
#261 = FACE_BOUND('',#262,.F.);
|
||||
#262 = EDGE_LOOP('',(#263,#264,#272,#278));
|
||||
#263 = ORIENTED_EDGE('',*,*,#137,.F.);
|
||||
#264 = ORIENTED_EDGE('',*,*,#265,.T.);
|
||||
#265 = EDGE_CURVE('',#129,#266,#268,.T.);
|
||||
#266 = VERTEX_POINT('',#267);
|
||||
#267 = CARTESIAN_POINT('',(12.,5.,-2.1));
|
||||
#268 = LINE('',#269,#270);
|
||||
#269 = CARTESIAN_POINT('',(1.521005543736E-15,5.,-2.1));
|
||||
#270 = VECTOR('',#271,1.);
|
||||
#271 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#272 = ORIENTED_EDGE('',*,*,#273,.T.);
|
||||
#273 = EDGE_CURVE('',#266,#218,#274,.T.);
|
||||
#274 = LINE('',#275,#276);
|
||||
#275 = CARTESIAN_POINT('',(12.,5.,-3.1));
|
||||
#276 = VECTOR('',#277,1.);
|
||||
#277 = DIRECTION('',(-2.22044604925E-16,2.22044604925E-16,1.));
|
||||
#278 = ORIENTED_EDGE('',*,*,#226,.F.);
|
||||
#279 = PLANE('',#280);
|
||||
#280 = AXIS2_PLACEMENT_3D('',#281,#282,#283);
|
||||
#281 = CARTESIAN_POINT('',(1.798561299893E-15,5.,-3.1));
|
||||
#282 = DIRECTION('',(-2.22044604925E-16,-1.,2.22044604925E-16));
|
||||
#283 = DIRECTION('',(-2.22044604925E-16,2.22044604925E-16,1.));
|
||||
#284 = ADVANCED_FACE('',(#285),#303,.T.);
|
||||
#285 = FACE_BOUND('',#286,.T.);
|
||||
#286 = EDGE_LOOP('',(#287,#295,#301,#302));
|
||||
#287 = ORIENTED_EDGE('',*,*,#288,.T.);
|
||||
#288 = EDGE_CURVE('',#48,#289,#291,.T.);
|
||||
#289 = VERTEX_POINT('',#290);
|
||||
#290 = CARTESIAN_POINT('',(12.,-12.,0.5));
|
||||
#291 = LINE('',#292,#293);
|
||||
#292 = CARTESIAN_POINT('',(-2.775557561563E-15,-12.,0.5));
|
||||
#293 = VECTOR('',#294,1.);
|
||||
#294 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#295 = ORIENTED_EDGE('',*,*,#296,.T.);
|
||||
#296 = EDGE_CURVE('',#289,#242,#297,.T.);
|
||||
#297 = LINE('',#298,#299);
|
||||
#298 = CARTESIAN_POINT('',(12.,-12.,0.5));
|
||||
#299 = VECTOR('',#300,1.);
|
||||
#300 = DIRECTION('',(-2.22044604925E-16,-1.,2.22044604925E-16));
|
||||
#301 = ORIENTED_EDGE('',*,*,#241,.F.);
|
||||
#302 = ORIENTED_EDGE('',*,*,#47,.F.);
|
||||
#303 = PLANE('',#304);
|
||||
#304 = AXIS2_PLACEMENT_3D('',#305,#306,#307);
|
||||
#305 = CARTESIAN_POINT('',(-2.775557561563E-15,-12.,0.5));
|
||||
#306 = DIRECTION('',(2.775557561563E-16,-2.22044604925E-16,-1.));
|
||||
#307 = DIRECTION('',(-2.22044604925E-16,-1.,2.22044604925E-16));
|
||||
#308 = ADVANCED_FACE('',(#309),#328,.T.);
|
||||
#309 = FACE_BOUND('',#310,.T.);
|
||||
#310 = EDGE_LOOP('',(#311,#312,#313,#322));
|
||||
#311 = ORIENTED_EDGE('',*,*,#128,.T.);
|
||||
#312 = ORIENTED_EDGE('',*,*,#265,.T.);
|
||||
#313 = ORIENTED_EDGE('',*,*,#314,.F.);
|
||||
#314 = EDGE_CURVE('',#315,#266,#317,.T.);
|
||||
#315 = VERTEX_POINT('',#316);
|
||||
#316 = CARTESIAN_POINT('',(12.,4.,-3.1));
|
||||
#317 = CIRCLE('',#318,1.);
|
||||
#318 = AXIS2_PLACEMENT_3D('',#319,#320,#321);
|
||||
#319 = CARTESIAN_POINT('',(12.,4.,-2.1));
|
||||
#320 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#321 = DIRECTION('',(-2.775557561563E-16,0.,1.));
|
||||
#322 = ORIENTED_EDGE('',*,*,#323,.F.);
|
||||
#323 = EDGE_CURVE('',#121,#315,#324,.T.);
|
||||
#324 = LINE('',#325,#326);
|
||||
#325 = CARTESIAN_POINT('',(1.576516694968E-15,4.,-3.1));
|
||||
#326 = VECTOR('',#327,1.);
|
||||
#327 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#328 = CYLINDRICAL_SURFACE('',#329,1.);
|
||||
#329 = AXIS2_PLACEMENT_3D('',#330,#331,#332);
|
||||
#330 = CARTESIAN_POINT('',(1.298960938811E-15,4.,-2.1));
|
||||
#331 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#332 = DIRECTION('',(2.775557561563E-16,-2.22044604925E-16,-1.));
|
||||
#333 = ADVANCED_FACE('',(#334),#352,.T.);
|
||||
#334 = FACE_BOUND('',#335,.T.);
|
||||
#335 = EDGE_LOOP('',(#336,#344,#350,#351));
|
||||
#336 = ORIENTED_EDGE('',*,*,#337,.T.);
|
||||
#337 = EDGE_CURVE('',#56,#338,#340,.T.);
|
||||
#338 = VERTEX_POINT('',#339);
|
||||
#339 = CARTESIAN_POINT('',(12.,-12.,1.5));
|
||||
#340 = LINE('',#341,#342);
|
||||
#341 = CARTESIAN_POINT('',(-2.997602166488E-15,-12.,1.5));
|
||||
#342 = VECTOR('',#343,1.);
|
||||
#343 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#344 = ORIENTED_EDGE('',*,*,#345,.T.);
|
||||
#345 = EDGE_CURVE('',#338,#289,#346,.T.);
|
||||
#346 = LINE('',#347,#348);
|
||||
#347 = CARTESIAN_POINT('',(12.,-12.,1.5));
|
||||
#348 = VECTOR('',#349,1.);
|
||||
#349 = DIRECTION('',(2.22044604925E-16,-2.22044604925E-16,-1.));
|
||||
#350 = ORIENTED_EDGE('',*,*,#288,.F.);
|
||||
#351 = ORIENTED_EDGE('',*,*,#55,.F.);
|
||||
#352 = PLANE('',#353);
|
||||
#353 = AXIS2_PLACEMENT_3D('',#354,#355,#356);
|
||||
#354 = CARTESIAN_POINT('',(-2.997602166488E-15,-12.,1.5));
|
||||
#355 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#356 = DIRECTION('',(2.22044604925E-16,-2.22044604925E-16,-1.));
|
||||
#357 = ADVANCED_FACE('',(#358),#376,.F.);
|
||||
#358 = FACE_BOUND('',#359,.F.);
|
||||
#359 = EDGE_LOOP('',(#360,#361,#369,#375));
|
||||
#360 = ORIENTED_EDGE('',*,*,#120,.F.);
|
||||
#361 = ORIENTED_EDGE('',*,*,#362,.T.);
|
||||
#362 = EDGE_CURVE('',#112,#363,#365,.T.);
|
||||
#363 = VERTEX_POINT('',#364);
|
||||
#364 = CARTESIAN_POINT('',(12.,-9.,-3.1));
|
||||
#365 = LINE('',#366,#367);
|
||||
#366 = CARTESIAN_POINT('',(-1.310063169058E-15,-9.,-3.1));
|
||||
#367 = VECTOR('',#368,1.);
|
||||
#368 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#369 = ORIENTED_EDGE('',*,*,#370,.T.);
|
||||
#370 = EDGE_CURVE('',#363,#315,#371,.T.);
|
||||
#371 = LINE('',#372,#373);
|
||||
#372 = CARTESIAN_POINT('',(12.,-10.,-3.1));
|
||||
#373 = VECTOR('',#374,1.);
|
||||
#374 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#375 = ORIENTED_EDGE('',*,*,#323,.F.);
|
||||
#376 = PLANE('',#377);
|
||||
#377 = AXIS2_PLACEMENT_3D('',#378,#379,#380);
|
||||
#378 = CARTESIAN_POINT('',(-1.532107773983E-15,-10.,-3.1));
|
||||
#379 = DIRECTION('',(-2.775557561563E-16,2.22044604925E-16,1.));
|
||||
#380 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#381 = ADVANCED_FACE('',(#382),#400,.F.);
|
||||
#382 = FACE_BOUND('',#383,.F.);
|
||||
#383 = EDGE_LOOP('',(#384,#385,#393,#399));
|
||||
#384 = ORIENTED_EDGE('',*,*,#337,.T.);
|
||||
#385 = ORIENTED_EDGE('',*,*,#386,.T.);
|
||||
#386 = EDGE_CURVE('',#338,#387,#389,.T.);
|
||||
#387 = VERTEX_POINT('',#388);
|
||||
#388 = CARTESIAN_POINT('',(12.,3.5,1.5));
|
||||
#389 = LINE('',#390,#391);
|
||||
#390 = CARTESIAN_POINT('',(12.,-12.,1.5));
|
||||
#391 = VECTOR('',#392,1.);
|
||||
#392 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#393 = ORIENTED_EDGE('',*,*,#394,.F.);
|
||||
#394 = EDGE_CURVE('',#64,#387,#395,.T.);
|
||||
#395 = LINE('',#396,#397);
|
||||
#396 = CARTESIAN_POINT('',(4.440892098501E-16,3.5,1.5));
|
||||
#397 = VECTOR('',#398,1.);
|
||||
#398 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#399 = ORIENTED_EDGE('',*,*,#63,.F.);
|
||||
#400 = PLANE('',#401);
|
||||
#401 = AXIS2_PLACEMENT_3D('',#402,#403,#404);
|
||||
#402 = CARTESIAN_POINT('',(-2.997602166488E-15,-12.,1.5));
|
||||
#403 = DIRECTION('',(-2.775557561563E-16,2.22044604925E-16,1.));
|
||||
#404 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#405 = ADVANCED_FACE('',(#406),#425,.T.);
|
||||
#406 = FACE_BOUND('',#407,.T.);
|
||||
#407 = EDGE_LOOP('',(#408,#409,#410,#419));
|
||||
#408 = ORIENTED_EDGE('',*,*,#111,.T.);
|
||||
#409 = ORIENTED_EDGE('',*,*,#362,.T.);
|
||||
#410 = ORIENTED_EDGE('',*,*,#411,.F.);
|
||||
#411 = EDGE_CURVE('',#412,#363,#414,.T.);
|
||||
#412 = VERTEX_POINT('',#413);
|
||||
#413 = CARTESIAN_POINT('',(12.,-10.,-2.1));
|
||||
#414 = CIRCLE('',#415,1.);
|
||||
#415 = AXIS2_PLACEMENT_3D('',#416,#417,#418);
|
||||
#416 = CARTESIAN_POINT('',(12.,-9.,-2.1));
|
||||
#417 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#418 = DIRECTION('',(-2.775557561563E-16,0.,1.));
|
||||
#419 = ORIENTED_EDGE('',*,*,#420,.F.);
|
||||
#420 = EDGE_CURVE('',#104,#412,#421,.T.);
|
||||
#421 = LINE('',#422,#423);
|
||||
#422 = CARTESIAN_POINT('',(-1.809663530139E-15,-10.,-2.1));
|
||||
#423 = VECTOR('',#424,1.);
|
||||
#424 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#425 = CYLINDRICAL_SURFACE('',#426,1.);
|
||||
#426 = AXIS2_PLACEMENT_3D('',#427,#428,#429);
|
||||
#427 = CARTESIAN_POINT('',(-1.587618925214E-15,-9.,-2.1));
|
||||
#428 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#429 = DIRECTION('',(-2.22044604925E-16,-1.,2.22044604925E-16));
|
||||
#430 = ADVANCED_FACE('',(#431),#449,.F.);
|
||||
#431 = FACE_BOUND('',#432,.F.);
|
||||
#432 = EDGE_LOOP('',(#433,#434,#442,#448));
|
||||
#433 = ORIENTED_EDGE('',*,*,#394,.T.);
|
||||
#434 = ORIENTED_EDGE('',*,*,#435,.T.);
|
||||
#435 = EDGE_CURVE('',#387,#436,#438,.T.);
|
||||
#436 = VERTEX_POINT('',#437);
|
||||
#437 = CARTESIAN_POINT('',(12.,3.5,2.553512956638E-15));
|
||||
#438 = LINE('',#439,#440);
|
||||
#439 = CARTESIAN_POINT('',(12.,3.5,1.5));
|
||||
#440 = VECTOR('',#441,1.);
|
||||
#441 = DIRECTION('',(2.22044604925E-16,-2.22044604925E-16,-1.));
|
||||
#442 = ORIENTED_EDGE('',*,*,#443,.F.);
|
||||
#443 = EDGE_CURVE('',#72,#436,#444,.T.);
|
||||
#444 = LINE('',#445,#446);
|
||||
#445 = CARTESIAN_POINT('',(7.771561172376E-16,3.5,-7.771561172376E-16));
|
||||
#446 = VECTOR('',#447,1.);
|
||||
#447 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#448 = ORIENTED_EDGE('',*,*,#71,.F.);
|
||||
#449 = PLANE('',#450);
|
||||
#450 = AXIS2_PLACEMENT_3D('',#451,#452,#453);
|
||||
#451 = CARTESIAN_POINT('',(4.440892098501E-16,3.5,1.5));
|
||||
#452 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#453 = DIRECTION('',(2.22044604925E-16,-2.22044604925E-16,-1.));
|
||||
#454 = ADVANCED_FACE('',(#455),#473,.F.);
|
||||
#455 = FACE_BOUND('',#456,.F.);
|
||||
#456 = EDGE_LOOP('',(#457,#458,#466,#472));
|
||||
#457 = ORIENTED_EDGE('',*,*,#103,.F.);
|
||||
#458 = ORIENTED_EDGE('',*,*,#459,.T.);
|
||||
#459 = EDGE_CURVE('',#96,#460,#462,.T.);
|
||||
#460 = VERTEX_POINT('',#461);
|
||||
#461 = CARTESIAN_POINT('',(12.,-10.,-1.6));
|
||||
#462 = LINE('',#463,#464);
|
||||
#463 = CARTESIAN_POINT('',(-1.86517468137E-15,-10.,-1.6));
|
||||
#464 = VECTOR('',#465,1.);
|
||||
#465 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#466 = ORIENTED_EDGE('',*,*,#467,.T.);
|
||||
#467 = EDGE_CURVE('',#460,#412,#468,.T.);
|
||||
#468 = LINE('',#469,#470);
|
||||
#469 = CARTESIAN_POINT('',(12.,-10.,-1.6));
|
||||
#470 = VECTOR('',#471,1.);
|
||||
#471 = DIRECTION('',(2.22044604925E-16,-2.22044604925E-16,-1.));
|
||||
#472 = ORIENTED_EDGE('',*,*,#420,.F.);
|
||||
#473 = PLANE('',#474);
|
||||
#474 = AXIS2_PLACEMENT_3D('',#475,#476,#477);
|
||||
#475 = CARTESIAN_POINT('',(-1.86517468137E-15,-10.,-1.6));
|
||||
#476 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#477 = DIRECTION('',(2.22044604925E-16,-2.22044604925E-16,-1.));
|
||||
#478 = ADVANCED_FACE('',(#479),#497,.F.);
|
||||
#479 = FACE_BOUND('',#480,.F.);
|
||||
#480 = EDGE_LOOP('',(#481,#482,#490,#496));
|
||||
#481 = ORIENTED_EDGE('',*,*,#443,.T.);
|
||||
#482 = ORIENTED_EDGE('',*,*,#483,.T.);
|
||||
#483 = EDGE_CURVE('',#436,#484,#486,.T.);
|
||||
#484 = VERTEX_POINT('',#485);
|
||||
#485 = CARTESIAN_POINT('',(12.,-2.6645352591E-15,3.330669073875E-15));
|
||||
#486 = LINE('',#487,#488);
|
||||
#487 = CARTESIAN_POINT('',(12.,3.5,2.553512956638E-15));
|
||||
#488 = VECTOR('',#489,1.);
|
||||
#489 = DIRECTION('',(-2.22044604925E-16,-1.,2.22044604925E-16));
|
||||
#490 = ORIENTED_EDGE('',*,*,#491,.F.);
|
||||
#491 = EDGE_CURVE('',#80,#484,#492,.T.);
|
||||
#492 = LINE('',#493,#494);
|
||||
#493 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#494 = VECTOR('',#495,1.);
|
||||
#495 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#496 = ORIENTED_EDGE('',*,*,#79,.F.);
|
||||
#497 = PLANE('',#498);
|
||||
#498 = AXIS2_PLACEMENT_3D('',#499,#500,#501);
|
||||
#499 = CARTESIAN_POINT('',(7.771561172376E-16,3.5,-7.771561172376E-16));
|
||||
#500 = DIRECTION('',(2.775557561563E-16,-2.22044604925E-16,-1.));
|
||||
#501 = DIRECTION('',(-2.22044604925E-16,-1.,2.22044604925E-16));
|
||||
#502 = ADVANCED_FACE('',(#503),#521,.F.);
|
||||
#503 = FACE_BOUND('',#504,.F.);
|
||||
#504 = EDGE_LOOP('',(#505,#513,#519,#520));
|
||||
#505 = ORIENTED_EDGE('',*,*,#506,.T.);
|
||||
#506 = EDGE_CURVE('',#88,#507,#509,.T.);
|
||||
#507 = VERTEX_POINT('',#508);
|
||||
#508 = CARTESIAN_POINT('',(12.,-3.01980662698E-15,-1.6));
|
||||
#509 = LINE('',#510,#511);
|
||||
#510 = CARTESIAN_POINT('',(3.552713678801E-16,-3.552713678801E-16,-1.6)
|
||||
);
|
||||
#511 = VECTOR('',#512,1.);
|
||||
#512 = DIRECTION('',(1.,-2.22044604925E-16,2.775557561563E-16));
|
||||
#513 = ORIENTED_EDGE('',*,*,#514,.T.);
|
||||
#514 = EDGE_CURVE('',#507,#460,#515,.T.);
|
||||
#515 = LINE('',#516,#517);
|
||||
#516 = CARTESIAN_POINT('',(12.,-3.01980662698E-15,-1.6));
|
||||
#517 = VECTOR('',#518,1.);
|
||||
#518 = DIRECTION('',(-2.22044604925E-16,-1.,2.22044604925E-16));
|
||||
#519 = ORIENTED_EDGE('',*,*,#459,.F.);
|
||||
#520 = ORIENTED_EDGE('',*,*,#95,.F.);
|
||||
#521 = PLANE('',#522);
|
||||
#522 = AXIS2_PLACEMENT_3D('',#523,#524,#525);
|
||||
#523 = CARTESIAN_POINT('',(3.552713678801E-16,-3.552713678801E-16,-1.6)
|
||||
);
|
||||
#524 = DIRECTION('',(2.775557561563E-16,-2.22044604925E-16,-1.));
|
||||
#525 = DIRECTION('',(-2.22044604925E-16,-1.,2.22044604925E-16));
|
||||
#526 = ADVANCED_FACE('',(#527),#538,.F.);
|
||||
#527 = FACE_BOUND('',#528,.F.);
|
||||
#528 = EDGE_LOOP('',(#529,#530,#536,#537));
|
||||
#529 = ORIENTED_EDGE('',*,*,#491,.T.);
|
||||
#530 = ORIENTED_EDGE('',*,*,#531,.T.);
|
||||
#531 = EDGE_CURVE('',#484,#507,#532,.T.);
|
||||
#532 = LINE('',#533,#534);
|
||||
#533 = CARTESIAN_POINT('',(12.,-2.6645352591E-15,3.330669073875E-15));
|
||||
#534 = VECTOR('',#535,1.);
|
||||
#535 = DIRECTION('',(2.22044604925E-16,-2.22044604925E-16,-1.));
|
||||
#536 = ORIENTED_EDGE('',*,*,#506,.F.);
|
||||
#537 = ORIENTED_EDGE('',*,*,#87,.F.);
|
||||
#538 = PLANE('',#539);
|
||||
#539 = AXIS2_PLACEMENT_3D('',#540,#541,#542);
|
||||
#540 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#541 = DIRECTION('',(2.22044604925E-16,1.,-2.22044604925E-16));
|
||||
#542 = DIRECTION('',(2.22044604925E-16,-2.22044604925E-16,-1.));
|
||||
#543 = ADVANCED_FACE('',(#544),#562,.T.);
|
||||
#544 = FACE_BOUND('',#545,.T.);
|
||||
#545 = EDGE_LOOP('',(#546,#547,#548,#549,#550,#551,#552,#553,#554,#555,
|
||||
#556,#557,#558,#559,#560,#561));
|
||||
#546 = ORIENTED_EDGE('',*,*,#169,.F.);
|
||||
#547 = ORIENTED_EDGE('',*,*,#193,.T.);
|
||||
#548 = ORIENTED_EDGE('',*,*,#249,.F.);
|
||||
#549 = ORIENTED_EDGE('',*,*,#296,.F.);
|
||||
#550 = ORIENTED_EDGE('',*,*,#345,.F.);
|
||||
#551 = ORIENTED_EDGE('',*,*,#386,.T.);
|
||||
#552 = ORIENTED_EDGE('',*,*,#435,.T.);
|
||||
#553 = ORIENTED_EDGE('',*,*,#483,.T.);
|
||||
#554 = ORIENTED_EDGE('',*,*,#531,.T.);
|
||||
#555 = ORIENTED_EDGE('',*,*,#514,.T.);
|
||||
#556 = ORIENTED_EDGE('',*,*,#467,.T.);
|
||||
#557 = ORIENTED_EDGE('',*,*,#411,.T.);
|
||||
#558 = ORIENTED_EDGE('',*,*,#370,.T.);
|
||||
#559 = ORIENTED_EDGE('',*,*,#314,.T.);
|
||||
#560 = ORIENTED_EDGE('',*,*,#273,.T.);
|
||||
#561 = ORIENTED_EDGE('',*,*,#217,.T.);
|
||||
#562 = PLANE('',#563);
|
||||
#563 = AXIS2_PLACEMENT_3D('',#564,#565,#566);
|
||||
#564 = CARTESIAN_POINT('',(12.,-3.444301816353,4.086646542781E-02));
|
||||
#565 = DIRECTION('',(1.,0.,2.22044604925E-16));
|
||||
#566 = DIRECTION('',(-2.22044604925E-16,0.,1.));
|
||||
#567 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3)
|
||||
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#571)) GLOBAL_UNIT_ASSIGNED_CONTEXT
|
||||
((#568,#569,#570)) REPRESENTATION_CONTEXT('Context #1',
|
||||
'3D Context with UNIT and UNCERTAINTY') );
|
||||
#568 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
|
||||
#569 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
|
||||
#570 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
|
||||
#571 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#568,
|
||||
'distance_accuracy_value','confusion accuracy');
|
||||
#572 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7));
|
||||
#573 = MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#574)
|
||||
,#567);
|
||||
#574 = STYLED_ITEM('color',(#575),#15);
|
||||
#575 = PRESENTATION_STYLE_ASSIGNMENT((#576,#582));
|
||||
#576 = SURFACE_STYLE_USAGE(.BOTH.,#577);
|
||||
#577 = SURFACE_SIDE_STYLE('',(#578));
|
||||
#578 = SURFACE_STYLE_FILL_AREA(#579);
|
||||
#579 = FILL_AREA_STYLE('',(#580));
|
||||
#580 = FILL_AREA_STYLE_COLOUR('',#581);
|
||||
#581 = COLOUR_RGB('',0.800000010877,0.800000010877,0.800000010877);
|
||||
#582 = CURVE_STYLE('',#583,POSITIVE_LENGTH_MEASURE(0.1),#584);
|
||||
#583 = DRAUGHTING_PRE_DEFINED_CURVE_FONT('continuous');
|
||||
#584 = COLOUR_RGB('',9.803921802644E-02,9.803921802644E-02,
|
||||
9.803921802644E-02);
|
||||
ENDSEC;
|
||||
END-ISO-10303-21;
|
BIN
cad/teensy40_sdcard_cover.FCStd
Normal file
BIN
cad/teensy40_sdcard_cover.FCStd
Normal file
Binary file not shown.
|
@ -14,6 +14,7 @@
|
|||
"/home/fisch/.platformio/packages/framework-arduinoteensy/libraries/SdFat/src",
|
||||
"/home/fisch/.platformio/packages/framework-arduinoteensy/libraries/Time",
|
||||
"/media/fisch/HDD/Projects/bobbycar/bobbycar_repo/controller_teensy/lib/hoverboard-esc-serial-comm/src",
|
||||
"/media/fisch/HDD/Projects/bobbycar/bobbycar_repo/controller_teensy/.pio/libdeps/teensy41/PulsePosition",
|
||||
"/media/fisch/HDD/Projects/bobbycar/bobbycar_repo/controller_teensy/.pio/libdeps/teensy41/DallasTemperature",
|
||||
"/media/fisch/HDD/Projects/bobbycar/bobbycar_repo/controller_teensy/.pio/libdeps/teensy41/OneWire",
|
||||
"/home/fisch/.platformio/packages/framework-arduinoteensy/libraries/VirtualWire",
|
||||
|
@ -129,6 +130,7 @@
|
|||
"/home/fisch/.platformio/packages/framework-arduinoteensy/libraries/SdFat/src",
|
||||
"/home/fisch/.platformio/packages/framework-arduinoteensy/libraries/Time",
|
||||
"/media/fisch/HDD/Projects/bobbycar/bobbycar_repo/controller_teensy/lib/hoverboard-esc-serial-comm/src",
|
||||
"/media/fisch/HDD/Projects/bobbycar/bobbycar_repo/controller_teensy/.pio/libdeps/teensy41/PulsePosition",
|
||||
"/media/fisch/HDD/Projects/bobbycar/bobbycar_repo/controller_teensy/.pio/libdeps/teensy41/DallasTemperature",
|
||||
"/media/fisch/HDD/Projects/bobbycar/bobbycar_repo/controller_teensy/.pio/libdeps/teensy41/OneWire",
|
||||
"/home/fisch/.platformio/packages/framework-arduinoteensy/libraries/VirtualWire",
|
||||
|
|
47
controller_teensy/.vscode/settings.json
vendored
47
controller_teensy/.vscode/settings.json
vendored
|
@ -1,3 +1,48 @@
|
|||
{
|
||||
"cmake.configureOnOpen": false
|
||||
"cmake.configureOnOpen": false,
|
||||
"files.associations": {
|
||||
"algorithm": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"random": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"limits": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
}
|
||||
}
|
78
controller_teensy/README.md
Normal file
78
controller_teensy/README.md
Normal file
|
@ -0,0 +1,78 @@
|
|||
# Bobbycar Controller
|
||||
|
||||
## Serial Commands
|
||||
|
||||
If Vusb jumper on PCB is soldered, do not connect USB while LiPo is connected!
|
||||
|
||||
**echo off**
|
||||
|
||||
Turn off serial command echo.
|
||||
Useful for automated transfer.
|
||||
|
||||
**echo on**
|
||||
|
||||
Turns on serial command echo.
|
||||
Useful for manual command execution.
|
||||
|
||||
**test**
|
||||
|
||||
Returns "OK"
|
||||
|
||||
**ls**
|
||||
|
||||
List files on SD card in a machine readable way.
|
||||
One file per line with full path.
|
||||
|
||||
**la -a**
|
||||
|
||||
List files tab formatted. With file sizes.
|
||||
|
||||
|
||||
**cat FILENAME**
|
||||
|
||||
Print out the contents of a specified file.
|
||||
|
||||
If no filename given, the current active logfile is used.
|
||||
|
||||
**get FILENAME**
|
||||
|
||||
Sends the contents of a specified file in chunks.
|
||||
Waits for the checksum of the send chunks before sending the next chunk.
|
||||
Exits with an error message when checksum does not match.
|
||||
Used for automated transfer of files.
|
||||
|
||||
**sizeof FILENAME**
|
||||
|
||||
Returns the size in bytes of the specified file.
|
||||
|
||||
**chunksize SIZE**
|
||||
|
||||
Sets the size of chunks for file transmission. See **get** command.
|
||||
Default is 128.
|
||||
|
||||
**rm FILENAME**
|
||||
|
||||
Deletes file from sd card.
|
||||
|
||||
**log off**
|
||||
|
||||
Turns off logging flag.
|
||||
|
||||
**log on**
|
||||
|
||||
Turns on logging flag.
|
||||
|
||||
**show stats**
|
||||
|
||||
Prints some current stats values.
|
||||
One variable per line.
|
||||
|
||||
Format: parametername\<Tab\>value
|
||||
|
||||
**show sensors**
|
||||
|
||||
Prints some sensor values that are useful in standstill.
|
||||
One variable per line.
|
||||
|
||||
Format: parametername\<Tab\>value
|
||||
|
|
@ -29,17 +29,25 @@ bool controllers_connected=false;
|
|||
|
||||
//const uint16_t calib_throttle_min = 420; //better a bit too high than too low
|
||||
//const uint16_t calib_throttle_max = 790;
|
||||
/*
|
||||
const uint16_t failsafe_throttle_min_A = 4900; //if adc value falls below this failsafe is triggered.
|
||||
const uint16_t failsafe_throttle_max_A = 14500; //if adc value goes above this failsafe is triggered.
|
||||
const uint16_t failsafe_throttle_min_B = 3900; //if adc value falls below this failsafe is triggered.
|
||||
const uint16_t failsafe_throttle_max_B = 12500; //if adc value goes above this failsafe is triggered.
|
||||
const uint16_t failsafe_throttle_maxDiff = 200;//maximum adc value difference between both sensors A and B. value range 0-1000. choose value at least 2x higher than maximum difference when moving throttle slowly
|
||||
//const uint16_t throttleCurvePerMM[] = {414,460,490,511,527,539,548,555,561,567,573,578,584,590,599,611,630,657,697,754,789,795}; //adc values for every unit (mm) of linear travel
|
||||
//const uint16_t throttleCurvePerMM[] = {8485,8904,9177,9368,9513,9623,9705,9768,9823,9877,9932,9978,10032,10087,10169,10278,10451,10697,11061,11579,11898,11952}; //adc values for every unit (mm) of linear travel. config used until 20230826
|
||||
*/
|
||||
|
||||
const uint16_t failsafe_throttle_min_A = 3000; //if adc value falls below this failsafe is triggered.
|
||||
const uint16_t failsafe_throttle_max_A = 13000; //if adc value goes above this failsafe is triggered.
|
||||
const uint16_t failsafe_throttle_min_B = 5000; //if adc value falls below this failsafe is triggered.
|
||||
const uint16_t failsafe_throttle_max_B = 14500; //if adc value goes above this failsafe is triggered.
|
||||
|
||||
const uint16_t failsafe_throttle_maxDiff = 200;//maximum throttle pos value difference between both sensors A and B (after linearization). value range 0-1000. choose value at least 2x higher than maximum difference when moving throttle slowly
|
||||
|
||||
//Throttle Calibration: First value pair should be 1-2mm pressed down (start of throttle=1). Last value pair should be a bit before fully pressed. all values in between need to be equidistant (for example every 1mm). Use define CALIBRATION_THROTTLE_CURVE for easy calibration output
|
||||
const uint16_t throttleCurvePerMM_A[] = {9996,9718,9507,9357,9232,9162,9071,8958,8838,8703,8577,8396,8192,7845,7407,6800,5923}; //adc values for every unit (mm) of linear travel
|
||||
const uint16_t throttleCurvePerMM_B[] = {7698,7948,8133,8277,8403,8503,8588,8695,8791,8899,9034,9196,9400,9711,10110,10657,1146}; //adc values for every unit (mm) of linear travel
|
||||
|
||||
const uint16_t throttleCurvePerMM_A[] = {11800,11130,10300,9990,9650,9470,9370,9240,9130,9030,8950,8850,8700,8560,8350,8040,7750,7150,6520}; //adc values for every unit (mm) of linear travel
|
||||
const bool throttleCurvePerMM_A_Descending=true; //set true if corresponding array is descending
|
||||
const uint16_t throttleCurvePerMM_B[] = {6200,6700,7420,7710,8030,8200,8310,8440,8560,8640,8740,8840,8990,9130,9330,9630,9900,10440,10990}; //adc values for every unit (mm) of linear travel
|
||||
const bool throttleCurvePerMM_B_Descending=false; //set true if corresponding array is descending
|
||||
|
||||
const uint16_t calib_brake_min = 7000; //better a bit too high than too low
|
||||
|
@ -59,28 +67,25 @@ uint16_t ads_brake_raw=failsafe_brake_min;
|
|||
uint16_t ads_control_raw=0;
|
||||
|
||||
|
||||
|
||||
|
||||
int16_t throttle_posA; //scaled and clamped throttle position for sensor A
|
||||
int16_t throttle_posB; //scaled and clamped throttle position for sensor B
|
||||
int16_t throttle_pos=0; //combined and filtered throttle position
|
||||
int16_t brake_pos=0; //filtered throttle position
|
||||
int16_t brake_pos=0; //filtered and constrained throttle position
|
||||
bool control_buttonA=false;
|
||||
bool control_buttonB=false;
|
||||
|
||||
|
||||
unsigned long loopmillis;
|
||||
unsigned long looptime_duration;
|
||||
unsigned long looptime_duration_min;
|
||||
unsigned long looptime_duration_max;
|
||||
|
||||
|
||||
#define ADSREADPERIOD 3 //set slightly higher as actual read time to avoid unnecessary register query
|
||||
#define ADCREADPERIOD 10
|
||||
#define BUTTONREADPERIOD 20
|
||||
unsigned long last_adsread=0; //needed for failcheck
|
||||
uint16_t throttle_rawA=failsafe_throttle_min_A; //start at min so that failsafe is not triggered
|
||||
uint16_t throttle_rawB=failsafe_throttle_min_B; //start at min so that failsafe is not triggered
|
||||
#define THROTTLE_ADC_FILTER 0.4 //higher value = faster response
|
||||
uint16_t brake_raw=failsafe_brake_min; //start at min so that failsafe is not triggered
|
||||
int16_t brake_linear=0; //linearized bake position
|
||||
#define ADC_OUTOFRANGE_TIME 100 //for failsafe_throttle_min_X. how long values need to stay bad to trigger failsafe
|
||||
#define ADC_DIFFHIGH_TIME 500 //for failsafe_throttle_maxDiff. how long values need to stay bad to trigger failsafe
|
||||
|
||||
|
@ -90,20 +95,21 @@ bool error_brake_outofrange=false;
|
|||
bool error_ads_max_read_interval=false;
|
||||
bool error_sdfile_unavailable=false;
|
||||
|
||||
#define REVERSE_ENABLE_TIME 1000 //ms. how long standstill to be able to drive backward
|
||||
#define REVERSE_ENABLE_TIME 300 //ms. how long standstill to be able to drive backward
|
||||
|
||||
|
||||
#define NORMAL_MAX_ACCELERATION_RATE 10000
|
||||
#define SLOW_MAX_ACCELERATION_RATE 500
|
||||
#define MEDIUM_MAX_ACCELERATION_RATE 500
|
||||
#define SLOW_MAX_ACCELERATION_RATE 250
|
||||
int16_t max_acceleration_rate=NORMAL_MAX_ACCELERATION_RATE; //maximum cmd send increase per second
|
||||
|
||||
|
||||
//Driving parameters
|
||||
int16_t minimum_constant_cmd_reduce=1; //reduce cmd every loop by this constant amount when freewheeling/braking
|
||||
int16_t brake_cmdreduce_proportional=500; //cmd gets reduced by an amount proportional to brake position (ignores freewheeling). cmd_new-=brake_cmdreduce_proportional / second @ full brake. with BREAK_CMDREDUCE_CONSTANT=1000 car would stop with full brake at least after a second (ignoring influence of brake current control/freewheeling)
|
||||
float startbrakecurrent=2; //Ampere. "targeted brake current @full brake". at what point to start apply brake proportional to brake_pos. for everything above that cmd is reduced by freewheel_break_factor
|
||||
float startbrakecurrent=2.0; //Ampere. "targeted brake current @full brake". at what point to start apply brake proportional to brake_pos. for everything above that cmd is reduced by freewheel_break_factor
|
||||
float startbrakecurrent_offset=0.13; //offset start point for breaking, because of reading fluctuations around 0A. set this slightly above idle current reading
|
||||
float freewheel_break_factor=500.0; //speed cmd units per amp per second. 1A over freewheel_current decreases cmd speed by this amount (on average)
|
||||
float freewheel_break_factor=200.0; //speed cmd units per amp per second. 1A over freewheel_current decreases cmd speed by this amount (on average). Was 500 until 20240809
|
||||
float reverse_speed=0.25; //reverse driving speed //0 to 1
|
||||
int16_t throttle_max=1000; //maximum allowed set speed. used for scaling and limiting. [0,1000]
|
||||
|
||||
|
@ -131,6 +137,8 @@ float max_filtered_wattAll;
|
|||
float min_filtered_wattAll;
|
||||
float max_meanSpeed;
|
||||
|
||||
float min_voltage;
|
||||
|
||||
float minSpeedms; //speed in m/s of slowest wheel
|
||||
double overallTrip; //m. trip with read distance from sd card
|
||||
double trip; //m. trip distance since boot
|
||||
|
|
|
@ -15,7 +15,12 @@
|
|||
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
|
||||
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||||
|
||||
uint8_t standingDisplayScreen=0;
|
||||
#define NUM_STANDINGDISPLAYSCREEN 5
|
||||
|
||||
#define DISPLAYSTANDSTILLTIME 5000
|
||||
|
||||
#include "rc.h"
|
||||
|
||||
bool display_init();
|
||||
void display_update(ESCSerialComm& escFront, ESCSerialComm& escRear);
|
||||
|
@ -81,17 +86,14 @@ void display_update(ESCSerialComm& escFront, ESCSerialComm& escRear){
|
|||
display.print(errorstring);
|
||||
|
||||
}else{
|
||||
//Normal Display Routinges here
|
||||
//Normal Display Routines here
|
||||
|
||||
if (armed) {
|
||||
if (loopmillis-last_notidle>5000) {
|
||||
if (loopmillis-last_notidle>DISPLAYSTANDSTILLTIME) {
|
||||
display_standingDisplay(escFront,escRear);
|
||||
}else{
|
||||
if (!control_buttonA) {
|
||||
display_drivingDisplay(escFront,escRear);
|
||||
}else{
|
||||
display_debugDisplay(escFront,escRear);
|
||||
}
|
||||
display_drivingDisplay(escFront,escRear);
|
||||
//display_debugDisplay(escFront,escRear);
|
||||
}
|
||||
|
||||
}else{
|
||||
|
@ -108,13 +110,16 @@ void display_update(ESCSerialComm& escFront, ESCSerialComm& escRear){
|
|||
|
||||
|
||||
void display_drivingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
||||
|
||||
//Display stuff here for when bobbycar is moving or was moving recently and is armed
|
||||
|
||||
|
||||
//## Km/h Display
|
||||
display.setFont(&FreeMonoBold18pt7b);
|
||||
display.setTextSize(1); // Normal 1:1 pixel scale
|
||||
display.setTextColor(SSD1306_WHITE); // Draw white text
|
||||
display.setCursor(0,SCREEN_HEIGHT-(SCREEN_HEIGHT-18)/2 - 3); // Start at top-left corner
|
||||
|
||||
|
||||
//float _speeddisplay=(escFront.getMeanSpeed()+escRear.getMeanSpeed())/2.0*3.6;
|
||||
float _speeddisplay=minSpeedms*3.6;
|
||||
|
||||
|
@ -132,6 +137,17 @@ void display_drivingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
|||
display.setCursor(SCREEN_WIDTH-25,SCREEN_HEIGHT-16);
|
||||
display.print("km/h");
|
||||
|
||||
#ifdef RC
|
||||
display.setCursor(0,0);
|
||||
if (rc_fullcontrol_enabled) {
|
||||
display.print("RC Fullcontrol");
|
||||
}else if(rc_steer_enabled){
|
||||
display.print("RC Steering");
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
//A
|
||||
display.setCursor(SCREEN_WIDTH-37,1);
|
||||
static float averaged_filtered_currentAll;
|
||||
|
@ -151,40 +167,36 @@ void display_drivingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
|||
|
||||
//## Trip / Current Consumed Display
|
||||
display.setCursor(1,SCREEN_HEIGHT-7);
|
||||
|
||||
//if (((millis()/2500)%2)==0) {
|
||||
if (control_buttonB) {
|
||||
//## Speed statistic
|
||||
display.print("max: ");
|
||||
dtostrf(max_meanSpeed*3.6,1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print("km/h");
|
||||
}else{
|
||||
//## Current Consumed
|
||||
/*
|
||||
dtostrf(min_filtered_currentAll,1,1,buf);
|
||||
display.print("min:");
|
||||
display.print((String)buf);
|
||||
display.print("A max:");
|
||||
|
||||
dtostrf(max_filtered_currentAll,1,1,buf);
|
||||
display.print((String)buf);
|
||||
display.print("A");
|
||||
*/
|
||||
//## Watt Hours Consumed
|
||||
dtostrf(min_filtered_wattAll,1,0,buf);
|
||||
display.print("min:");
|
||||
display.print((String)buf);
|
||||
display.print("W max:");
|
||||
//## Current
|
||||
/*
|
||||
dtostrf(min_filtered_currentAll,1,1,buf);
|
||||
display.print("min:");
|
||||
display.print((String)buf);
|
||||
display.print("A max:");
|
||||
|
||||
dtostrf(max_filtered_wattAll,1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print("W");
|
||||
}
|
||||
|
||||
dtostrf(max_filtered_currentAll,1,1,buf);
|
||||
display.print((String)buf);
|
||||
display.print("A");
|
||||
*/
|
||||
|
||||
//## Watt
|
||||
dtostrf(min_filtered_wattAll,1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print(" / ");
|
||||
|
||||
dtostrf(max_filtered_wattAll,1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print("W ");
|
||||
|
||||
display.setCursor(SCREEN_WIDTH-6*6,SCREEN_HEIGHT-7);
|
||||
dtostrf(max_meanSpeed*3.6,1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print("km/h");
|
||||
|
||||
}
|
||||
|
||||
|
||||
void display_debugDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
||||
//Debug
|
||||
display.setTextSize(2); // Normal 1:1 pixel scale
|
||||
|
@ -220,30 +232,172 @@ void display_debugDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
|||
display.print(" thrpos=");
|
||||
display.print(throttle_pos);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void display_standingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
||||
//Display stuff here when ESCs are powered on and bobbycar is armed but was not moving for a while
|
||||
|
||||
double _displaytrip=trip;
|
||||
//double _displaycurrent=currentConsumed;
|
||||
double _displaywatthours=watthoursConsumed;
|
||||
//bool _displayOverall= ((millis()/3000)%2==0); //switch based on time
|
||||
bool _displayOverall=control_buttonB; //switch with button
|
||||
bool _displayParameters=control_buttonA;
|
||||
bool _displayOverall= ((millis()/2500)%2==0); //switch based on time
|
||||
|
||||
|
||||
|
||||
|
||||
char buf[8];
|
||||
|
||||
display.setFont();
|
||||
display.setCursor(0,0);
|
||||
|
||||
if (_displayParameters) {
|
||||
|
||||
|
||||
if (_displayOverall) { //alternate between this trip and overall trip
|
||||
_displaytrip=overallTrip;
|
||||
//_displaycurrent=overallCurrentConsumed;
|
||||
_displaywatthours=overallWatthoursConsumed;
|
||||
}
|
||||
|
||||
|
||||
//Row 1
|
||||
if (!_displayOverall) {
|
||||
display.print(F("Vbat:")); display.print(escFront.getFeedback_batVoltage());
|
||||
display.print(F("/")); display.print(escRear.getFeedback_batVoltage());
|
||||
}else{
|
||||
display.print(F("Vmin:")); display.print(min_voltage);
|
||||
}
|
||||
display.print(" V");
|
||||
display.println();
|
||||
|
||||
|
||||
|
||||
//Row 2
|
||||
//display.print(F("Temp:")); display.print(escFront.getFeedback_boardTemp());
|
||||
//display.print(F("/")); display.print(escRear.getFeedback_boardTemp());
|
||||
display.print(F("T:")); display.print(temp_Front,0);
|
||||
display.print(F("/")); display.print(temp_Rear,0);
|
||||
display.print(F("/")); display.print(temp_Air,0);
|
||||
display.print(" C");
|
||||
display.println();
|
||||
|
||||
//Row 3
|
||||
display.print(F("Trip:"));
|
||||
dtostrf(_displaytrip,1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print("m ");
|
||||
//dtostrf(_displaycurrent,1,2,buf);
|
||||
dtostrf(_displaywatthours,1,2,buf);
|
||||
display.print((String)buf);
|
||||
//display.print(" Ah");
|
||||
display.print("Wh");
|
||||
display.println();
|
||||
|
||||
//Row 4
|
||||
|
||||
display.print(F(""));
|
||||
//dtostrf( _displaytrip/1000/_displaycurrent ,1,2,buf);
|
||||
dtostrf( _displaywatthours/_displaytrip*100,1,2,buf);
|
||||
display.print((String)buf);
|
||||
//display.print(" km/Ah");
|
||||
display.print(" kWh/100km");
|
||||
|
||||
if (_displayOverall){
|
||||
display.print(" sum");
|
||||
}
|
||||
|
||||
|
||||
display.println();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void display_standingDisarmedDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
||||
//Displayed stuff here when escs are powered off / disconnected or bobbycar is not armed
|
||||
char buf[8];
|
||||
display.setFont();
|
||||
display.setCursor(0,0);
|
||||
|
||||
|
||||
|
||||
switch(standingDisplayScreen)
|
||||
{
|
||||
case 0:
|
||||
//Quick overview of inputs and status
|
||||
|
||||
//Row1
|
||||
if (getDatalogging()) {
|
||||
display.print(getLogFilename());
|
||||
}else{
|
||||
display.print("LOG DISABLED");
|
||||
}
|
||||
|
||||
display.print(F(" ")); display.print(loopmillis/1000);
|
||||
display.print(F("s"));
|
||||
display.println();
|
||||
|
||||
//Row2
|
||||
|
||||
display.print(F("Throttle "));
|
||||
dtostrf((throttle_posA+throttle_posB)/2.0,4,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print(F(" ("));
|
||||
if (throttle_posA>throttle_posB) { //use values acutally taken for diff check
|
||||
display.print(F("+")); //add + for better formatting
|
||||
}
|
||||
dtostrf((throttle_posA-throttle_posB),1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print(F(")"));
|
||||
display.println();
|
||||
|
||||
//Row3
|
||||
|
||||
display.print("Brake ");
|
||||
dtostrf(brake_linear,4,0,buf); //use only linearized values (not constrained)
|
||||
display.print((String)buf);
|
||||
|
||||
display.setCursor(8*10,2*8);
|
||||
dtostrf((escFront.getFeedback_batVoltage()+escRear.getFeedback_batVoltage())/2.0,1,1,buf);
|
||||
display.print((String)buf);
|
||||
display.print(F("V"));
|
||||
display.println();
|
||||
|
||||
|
||||
|
||||
|
||||
/*display.print(" c=");
|
||||
dtostrf(ads_control_raw,1,0,buf);
|
||||
display.print((String)buf); */
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
//Trip Stats (trip / overall)
|
||||
|
||||
//Row 1
|
||||
display.print(F("Trip ")); display.print(trip,0); display.print(F(" / ")); display.print(overallTrip,0); display.print(F("m"));
|
||||
display.println();
|
||||
//Row 2
|
||||
display.print(F("Curr ")); display.print(currentConsumed*1000,0); display.print(F(" / ")); display.print(overallCurrentConsumed*1000,0); display.print(F("mAh"));
|
||||
display.println();
|
||||
//Row 3
|
||||
display.print(F("Pow ")); display.print(watthoursConsumed,0); display.print(F(" / ")); display.print(overallWatthoursConsumed,0); display.print(F("Wh"));
|
||||
display.println();
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
//Configuration parameters
|
||||
|
||||
//Row 1
|
||||
display.print(F("cmdred min=")); display.print(minimum_constant_cmd_reduce);
|
||||
display.print(F(" p=")); display.print(brake_cmdreduce_proportional);
|
||||
display.println();
|
||||
|
||||
//Row 2
|
||||
|
||||
display.print(F("brkI="));
|
||||
dtostrf(startbrakecurrent,1,1,buf);
|
||||
|
@ -254,105 +408,127 @@ void display_standingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
|||
display.print((String)buf);
|
||||
display.println();
|
||||
|
||||
//Row 3
|
||||
|
||||
display.print(F("thrmax=")); display.print(throttle_max);
|
||||
display.print(F(" rev="));
|
||||
dtostrf(reverse_speed,1,2,buf);
|
||||
display.print((String)buf);
|
||||
display.println();
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
//Raw inputs and Input Debug
|
||||
|
||||
//TODO: show deviation (and max deviation), show resulting throttle and brake pos
|
||||
|
||||
}else{
|
||||
|
||||
|
||||
if (_displayOverall) { //alternate between this trip and overall trip
|
||||
_displaytrip=overallTrip;
|
||||
//_displaycurrent=overallCurrentConsumed;
|
||||
_displaywatthours=overallWatthoursConsumed;
|
||||
//Row1
|
||||
|
||||
display.print(F("Throttle "));
|
||||
dtostrf(ads_throttle_A_raw,1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print(F("/"));
|
||||
dtostrf(ads_throttle_B_raw,1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.println();
|
||||
|
||||
//Row2
|
||||
static int16_t _throttle_maxdiff = 0;
|
||||
if (control_buttonA || control_buttonB) { //any button press
|
||||
_throttle_maxdiff=0; //reset maxdiff for this display
|
||||
}
|
||||
|
||||
display.print(F("Vbat:")); display.print(escFront.getFeedback_batVoltage());
|
||||
display.print(F("/")); display.print(escRear.getFeedback_batVoltage());
|
||||
display.print(" V");
|
||||
display.println();
|
||||
|
||||
//display.print(F("Temp:")); display.print(escFront.getFeedback_boardTemp());
|
||||
//display.print(F("/")); display.print(escRear.getFeedback_boardTemp());
|
||||
display.print(F("T:")); display.print(temp_ESCFront,0);
|
||||
display.print(F("/")); display.print(temp_ESCRear,0);
|
||||
display.print(F("/")); display.print(temp_Air,0);
|
||||
display.print(" C");
|
||||
display.println();
|
||||
|
||||
display.print(F("Trip:"));
|
||||
dtostrf(_displaytrip,1,0,buf);
|
||||
_throttle_maxdiff=max(_throttle_maxdiff,abs(throttle_posA-throttle_posB));
|
||||
display.print(F("Thr.maxdiff "));
|
||||
dtostrf(_throttle_maxdiff,1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print("m ");
|
||||
//dtostrf(_displaycurrent,1,2,buf);
|
||||
dtostrf(_displaywatthours,1,2,buf);
|
||||
display.print((String)buf);
|
||||
//display.print(" Ah");
|
||||
display.print("Wh");
|
||||
display.println();
|
||||
|
||||
display.print(F(""));
|
||||
//dtostrf( _displaytrip/1000/_displaycurrent ,1,2,buf);
|
||||
dtostrf( _displaywatthours/_displaytrip*100,1,2,buf);
|
||||
display.print((String)buf);
|
||||
//display.print(" km/Ah");
|
||||
display.print(" kWh/100km");
|
||||
|
||||
if (_displayOverall){
|
||||
display.print(" sum");
|
||||
}
|
||||
|
||||
//Row3
|
||||
|
||||
display.print("Brake ");
|
||||
dtostrf(ads_brake_raw,1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.println();
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 4:
|
||||
//Row 1
|
||||
display.print(F("RC "));
|
||||
dtostrf(ppm[0],4,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print(F("/"));
|
||||
dtostrf(ppm[1],4,0,buf);
|
||||
display.print((String)buf);
|
||||
display.println();
|
||||
|
||||
//Row 2
|
||||
|
||||
display.print(F("T"));
|
||||
dtostrf(getRCThrottle(),3,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print(F(" B"));
|
||||
dtostrf(getRCBrake(),3,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print(F(" S"));
|
||||
dtostrf(getRCSteer(),3,0,buf);
|
||||
display.print((String)buf);
|
||||
|
||||
display.println();
|
||||
|
||||
//Row 3
|
||||
display.print(F("Mode="));
|
||||
dtostrf(getRCMode(6),1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print(F(" %="));
|
||||
dtostrf(getPPMSuccessrate(),1,5,buf);
|
||||
display.print((String)buf);
|
||||
display.println();
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void display_standingDisarmedDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
||||
//Displayed stuff here when escs are powered off / disconnected
|
||||
char buf[8];
|
||||
display.setFont();
|
||||
display.setCursor(0,0);
|
||||
|
||||
display.print(getLogFilename());
|
||||
|
||||
display.print(F(" ")); display.print(loopmillis/1000);
|
||||
display.print(F("s"));
|
||||
display.println();
|
||||
|
||||
display.print(F("ESC F="));
|
||||
display.print(escFront.getControllerConnected());
|
||||
display.print(F(" R="));
|
||||
display.print(escRear.getControllerConnected());
|
||||
display.println();
|
||||
|
||||
|
||||
display.print("throttle=");
|
||||
dtostrf(ads_throttle_A_raw,1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.print("/");
|
||||
dtostrf(ads_throttle_B_raw,1,0,buf);
|
||||
display.print((String)buf);
|
||||
display.println();
|
||||
|
||||
display.print("brake=");
|
||||
dtostrf(ads_brake_raw,1,0,buf);
|
||||
display.print((String)buf);
|
||||
|
||||
/*display.print(" c=");
|
||||
dtostrf(ads_control_raw,1,0,buf);
|
||||
display.print((String)buf); */
|
||||
|
||||
if (control_buttonA){
|
||||
display.print(" A");
|
||||
//Put User Inputs in last row
|
||||
//Row 4
|
||||
display.setCursor(0,24);
|
||||
if (button_start_state){
|
||||
display.print("S");
|
||||
}else{
|
||||
display.print(" ");
|
||||
}
|
||||
if (control_buttonB){
|
||||
display.print(" B");
|
||||
display.print("B");
|
||||
}else{
|
||||
display.print(" ");
|
||||
}
|
||||
if (control_buttonA){
|
||||
display.print("A");
|
||||
}else{
|
||||
display.print(" ");
|
||||
}
|
||||
|
||||
if (escFront.getControllerConnected()){
|
||||
display.print("F");
|
||||
}else{
|
||||
display.print(" ");
|
||||
}
|
||||
if (escRear.getControllerConnected()){
|
||||
display.print("R");
|
||||
}else{
|
||||
display.print(" ");
|
||||
}
|
||||
|
||||
display.setCursor(SCREEN_WIDTH-6*3,24);
|
||||
display.print(standingDisplayScreen);
|
||||
display.print("/"); display.print(NUM_STANDINGDISPLAYSCREEN-1);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <Adafruit_NeoPixel.h>
|
||||
|
||||
|
||||
#define LED_PIN 3
|
||||
#define LED_PIN 20
|
||||
#define LED_COUNT 16
|
||||
|
||||
// NeoPixel brightness, 0 (min) to 255 (max)
|
||||
|
@ -31,6 +31,9 @@ unsigned long last_ledupdate=0;
|
|||
|
||||
uint8_t led_errorcount=0; //count led progress errors. used for delay at end if any errors occured
|
||||
|
||||
extern bool rc_fullcontrol_enabled; //from rc.h
|
||||
extern bool rc_steer_enabled;
|
||||
|
||||
void led_dotcircle(unsigned long loopmillis);
|
||||
void led_gauge(unsigned long loopmillis,float value,float value_min,float value_max,uint32_t colorGauge,uint32_t colorBG);
|
||||
|
||||
|
@ -109,18 +112,22 @@ void led_update(unsigned long loopmillis,ESCSerialComm& escFront, ESCSerialComm&
|
|||
}else{
|
||||
|
||||
if (armed) {
|
||||
if (loopmillis-last_notidle>5000) {
|
||||
//Standing
|
||||
float vbat=min(escRear.getFeedback_batVoltage(),escFront.getFeedback_batVoltage());
|
||||
led_gauge(loopmillis,vbat,3*12,4.2*12,strip.Color(0, 255, 0, 0),strip.Color(100, 0, 0, 0));
|
||||
}else{
|
||||
//Driving
|
||||
float currentMean=escRear.getFiltered_curL()+escRear.getFiltered_curR()+escFront.getFiltered_curL()+escFront.getFiltered_curR();
|
||||
uint32_t _bgColor=strip.Color(0, 0, 20, 0);
|
||||
if (reverse_enabled) {
|
||||
_bgColor=strip.Color(20, 0, 20, 0);
|
||||
if (rc_fullcontrol_enabled || rc_steer_enabled) {
|
||||
led_gauge(loopmillis,escFront.getCmdL(),0,1000,strip.Color(100, 0, 0, 0),strip.Color(0, 50, 50, 0));
|
||||
}else{ //normal driving
|
||||
if (loopmillis-last_notidle>5000) {
|
||||
//Standing
|
||||
float vbat=min(escRear.getFeedback_batVoltage(),escFront.getFeedback_batVoltage());
|
||||
led_gauge(loopmillis,vbat,3.3*12,4.2*12,strip.Color(0, 255, 0, 0),strip.Color(100, 0, 0, 0));
|
||||
}else{
|
||||
//Driving
|
||||
float currentMean=escRear.getFiltered_curL()+escRear.getFiltered_curR()+escFront.getFiltered_curL()+escFront.getFiltered_curR();
|
||||
uint32_t _bgColor=strip.Color(0, 0, 20, 0);
|
||||
if (reverse_enabled) {
|
||||
_bgColor=strip.Color(20, 0, 20, 0);
|
||||
}
|
||||
led_gauge(loopmillis,currentMean,0,32.0,strip.Color(0, 0, 0, 255),_bgColor);
|
||||
}
|
||||
led_gauge(loopmillis,currentMean,0,32.0,strip.Color(0, 0, 0, 255),_bgColor);
|
||||
}
|
||||
}else{
|
||||
//Disarmed
|
||||
|
|
|
@ -7,67 +7,109 @@
|
|||
#include <SD.h> //Format sd cart with FAT or FAT16. FAT32 for >1GB Cards on Teensy4.1
|
||||
|
||||
//#define SDCHIPSELECT 14
|
||||
boolean sdcard_available=false;
|
||||
boolean datalogging=true;
|
||||
String datalogging_filename="UNKNOWN.txt";
|
||||
|
||||
uint16_t chunksize=128; //for bulk data transmission
|
||||
|
||||
#define LOGGINGINTERVAL 100 //logging interval when driving
|
||||
#define LOGGINGSTANDSTILLTIME 30000 //after which time of standstill logging interval should change
|
||||
#define LOGGINGINTERVALSTANDSTILL 500 //logging interval when standing still
|
||||
#define LOGGINGINTERVALDISARMED 1000 //logging interval when disarmed
|
||||
|
||||
bool serialCommandEcho_Enabled=true;
|
||||
|
||||
bool initLogging();
|
||||
void loggingLoop(unsigned long loopmillis,ESCSerialComm& escFront, ESCSerialComm& escRear);
|
||||
|
||||
|
||||
void writeLogComment(unsigned long time, String msg);
|
||||
void printFileListing(bool pretty);
|
||||
void printDirectory(File dir, int numTabs,String parent,bool printSize,bool printFullDirectoryNames);
|
||||
void printFile(String filename);
|
||||
void printFilesize(String filename);
|
||||
void transferFile(String filename);
|
||||
void removeFile(String filename);
|
||||
void serialCommandLoop(unsigned long loopmillis, ESCSerialComm& escFront, ESCSerialComm& escRear);
|
||||
float getBatteryVoltage(ESCSerialComm& escFront, ESCSerialComm& escRear);
|
||||
|
||||
|
||||
bool initLogging() {
|
||||
Serial.print("Initializing SD card...");
|
||||
// see if the card is present and can be initialized:
|
||||
if (!SD.begin(BUILTIN_SDCARD)) {
|
||||
Serial.println("Card failed, or not present");
|
||||
display.println(F("SD Init Fail!")); display.display();
|
||||
datalogging=false; //disable logging
|
||||
delay(1000);
|
||||
return false;
|
||||
}else{
|
||||
Serial.println("Card initialized.");
|
||||
display.print(F("LOG=")); display.display();
|
||||
if (datalogging){
|
||||
int filenumber=0;
|
||||
char buffer[6];
|
||||
Serial.print("Datalogging is ");
|
||||
if (datalogging) {
|
||||
Serial.println("enabled");
|
||||
}else{
|
||||
Serial.println("disabled");
|
||||
}
|
||||
Serial.print("Initializing SD card...");
|
||||
// see if the card is present and can be initialized:
|
||||
if (!SD.begin(BUILTIN_SDCARD)) {
|
||||
Serial.println("Card failed, or not present");
|
||||
display.println(F("SD Init Fail!")); display.display();
|
||||
sdcard_available=false; //disable logging
|
||||
datalogging=false;
|
||||
delay(1000);
|
||||
return false;
|
||||
}else{
|
||||
sdcard_available=true;
|
||||
Serial.println("Card initialized.");
|
||||
display.print(F("LOG=")); display.display();
|
||||
|
||||
int filenumber=0;
|
||||
char buffer[6];
|
||||
sprintf(buffer, "%04d", filenumber);
|
||||
datalogging_filename="LOG_"+String(buffer)+".TXT";
|
||||
while(SD.exists(datalogging_filename.c_str()) && filenumber<10000) {
|
||||
//Serial.print(datalogging_filename); Serial.println(" exists");
|
||||
filenumber++;
|
||||
sprintf(buffer, "%04d", filenumber);
|
||||
datalogging_filename="LOG_"+String(buffer)+".TXT";
|
||||
while(SD.exists(datalogging_filename.c_str()) && filenumber<10000) {
|
||||
Serial.print(datalogging_filename); Serial.println(" exists");
|
||||
filenumber++;
|
||||
sprintf(buffer, "%04d", filenumber);
|
||||
datalogging_filename="LOG_"+String(buffer)+".TXT";
|
||||
|
||||
}
|
||||
Serial.print(datalogging_filename); Serial.println(" is free");
|
||||
display.print(datalogging_filename); display.println(); display.display();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Serial.print(datalogging_filename); Serial.println(" is free");
|
||||
display.print(datalogging_filename);
|
||||
if (!datalogging) { //datalogging is disabled during boot
|
||||
display.print(" OFF");
|
||||
}
|
||||
display.println(); display.display();
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void loggingLoop(unsigned long loopmillis,ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
||||
|
||||
static unsigned long last_datalogging_write=0;
|
||||
static unsigned long last_datalogging_write=loopmillis; //initialize with current time to have first log written after one interval
|
||||
static boolean logging_headerWritten=false;
|
||||
if (datalogging) {
|
||||
#define LOGGINGINTERVAL 100
|
||||
if (loopmillis-last_datalogging_write>LOGGINGINTERVAL)
|
||||
{
|
||||
last_datalogging_write=loopmillis;
|
||||
|
||||
File dataFile = SD.open(datalogging_filename.c_str(), FILE_WRITE);
|
||||
|
||||
unsigned long logginginterval=LOGGINGINTERVAL;
|
||||
if (armed) { //Change Logginginterval when less is happening
|
||||
if (loopmillis-last_notidle>LOGGINGSTANDSTILLTIME) {
|
||||
logginginterval=LOGGINGINTERVALSTANDSTILL;
|
||||
}
|
||||
}else{ //disamred
|
||||
logginginterval=LOGGINGINTERVALDISARMED;
|
||||
}
|
||||
|
||||
|
||||
if (loopmillis-last_datalogging_write>logginginterval)
|
||||
{
|
||||
last_datalogging_write=loopmillis;
|
||||
|
||||
if (datalogging && sdcard_available) {
|
||||
|
||||
File dataFile = SD.open(datalogging_filename.c_str(), FILE_WRITE);
|
||||
|
||||
if (dataFile) { // if the file is available, write to it
|
||||
if (!logging_headerWritten) {
|
||||
dataFile.print("time,cmd_FrontL,cmd_FrontR,cmd_RearL,cmd_RearR,");
|
||||
dataFile.print("current_FrontL,current_FrontR,current_RearL,current_RearR,");
|
||||
dataFile.print("rpm_FrontL,rpm_FrontR,rpm_RearL,rpm_RearR,");
|
||||
dataFile.print("temp_Front,temp_Rear,vbat_Front,vbat_Rear,");
|
||||
dataFile.print("temp_ESCFront,temp_ESCRear,vbat_Front,vbat_Rear,");
|
||||
dataFile.print("currentAll,throttle,brake,speed,trip_Front,trip_Rear,trip,currentConsumed_Front,currentConsumed_Rear,currentConsumed,watthoursConsumed,");
|
||||
dataFile.println("temp_ESCFront,temp_ESCRear,temp_Air,looptime_duration");
|
||||
dataFile.println("temp_Front,temp_Rear,temp_Air,looptime_duration_min,looptime_duration_max");
|
||||
dataFile.print("#TIMESTAMP:"); dataFile.println(now());
|
||||
logging_headerWritten=true;
|
||||
}
|
||||
|
@ -99,11 +141,15 @@ void loggingLoop(unsigned long loopmillis,ESCSerialComm& escFront, ESCSerialComm
|
|||
dataFile.print(escRear.getCurrentConsumed(),3); dataFile.print(",");
|
||||
dataFile.print(currentConsumed,3); dataFile.print(",");
|
||||
dataFile.print(watthoursConsumed,3); dataFile.print(",");
|
||||
dataFile.print(temp_ESCFront,2); dataFile.print(",");
|
||||
dataFile.print(temp_ESCRear,2); dataFile.print(",");
|
||||
dataFile.print(temp_Front,2); dataFile.print(",");
|
||||
dataFile.print(temp_Rear,2); dataFile.print(",");
|
||||
dataFile.print(temp_Air,2); dataFile.print(",");
|
||||
dataFile.print(looptime_duration); //dataFile.print(",");
|
||||
looptime_duration=0; //reset
|
||||
dataFile.print(looptime_duration_min); dataFile.print(",");
|
||||
dataFile.print(looptime_duration_max); //dataFile.print(",");
|
||||
looptime_duration_max=0; //reset
|
||||
looptime_duration_min=1000; //reset
|
||||
|
||||
|
||||
|
||||
dataFile.println("");
|
||||
dataFile.close();
|
||||
|
@ -111,12 +157,16 @@ void loggingLoop(unsigned long loopmillis,ESCSerialComm& escFront, ESCSerialComm
|
|||
error_sdfile_unavailable=true;
|
||||
}
|
||||
}
|
||||
|
||||
looptime_duration_max=0; //reset
|
||||
looptime_duration_min=1000; //reset
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void writeLogComment(unsigned long time, String msg) {
|
||||
//SerialRef.print("#"); SerialRef.print(time/1000.0,3); SerialRef.print(","); SerialRef.print(msg); SerialRef.println();
|
||||
if (datalogging) {
|
||||
if (datalogging && sdcard_available) {
|
||||
File dataFile = SD.open(datalogging_filename.c_str(), FILE_WRITE);
|
||||
|
||||
if (dataFile) { // if the file is available, write to it
|
||||
|
@ -134,6 +184,10 @@ String getLogFilename() {
|
|||
return datalogging_filename;
|
||||
}
|
||||
|
||||
bool getDatalogging() {
|
||||
return datalogging;
|
||||
}
|
||||
|
||||
bool loadTripSD()
|
||||
{
|
||||
//stats.txt containt lines with driven distance or consume current.
|
||||
|
@ -149,6 +203,7 @@ bool loadTripSD()
|
|||
myFile.close();
|
||||
Serial.println("TripSD: time written");
|
||||
}else{
|
||||
Serial.println("TripSD: could not open stats.txt");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -191,7 +246,7 @@ bool loadTripSD()
|
|||
}
|
||||
|
||||
void writeTrip(unsigned long loopmillis,ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
||||
if (datalogging) {
|
||||
if (datalogging && sdcard_available) {
|
||||
File myFile = SD.open("stats.txt", FILE_WRITE);
|
||||
if (myFile) {
|
||||
myFile.print("trp=");
|
||||
|
@ -201,15 +256,19 @@ void writeTrip(unsigned long loopmillis,ESCSerialComm& escFront, ESCSerialComm&
|
|||
myFile.print("owh=");
|
||||
myFile.println(overallWatthoursConsumed);
|
||||
myFile.print("vlt=");
|
||||
float _voltage=(escFront.getFeedback_batVoltage()+escRear.getFeedback_batVoltage())/2.0;
|
||||
float _voltage=getBatteryVoltage(escFront, escRear);
|
||||
myFile.println(_voltage,2);
|
||||
myFile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float getBatteryVoltage(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
||||
return (escFront.getFeedback_batVoltage()+escRear.getFeedback_batVoltage())/2.0;
|
||||
}
|
||||
|
||||
void resetTrip() {
|
||||
if (datalogging) {
|
||||
if (datalogging && sdcard_available) {
|
||||
File myFile = SD.open("stats.txt", FILE_WRITE);
|
||||
if (myFile) {
|
||||
myFile.print("trp=");
|
||||
|
@ -227,4 +286,260 @@ void resetTrip() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void serialCommandLoop(unsigned long loopmillis,ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
||||
#define MAX_MESSAGE_LENGTH 80
|
||||
|
||||
uint8_t timeoutcounter=MAX_MESSAGE_LENGTH;
|
||||
|
||||
while (Serial.available() > 0 && timeoutcounter>0)
|
||||
{
|
||||
timeoutcounter--;
|
||||
|
||||
static char message[MAX_MESSAGE_LENGTH];
|
||||
static unsigned int message_pos = 0;
|
||||
|
||||
char inByte = Serial.read();
|
||||
if (inByte == '\r') {
|
||||
break; //ignore CR
|
||||
}
|
||||
|
||||
|
||||
if ( inByte != '\n' && (message_pos < MAX_MESSAGE_LENGTH - 1) )
|
||||
{
|
||||
|
||||
message[message_pos] = inByte;
|
||||
message_pos++;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
message[message_pos] = '\0';
|
||||
|
||||
|
||||
String smessage=String(message);
|
||||
|
||||
if(smessage.equals("echo off")) {
|
||||
serialCommandEcho_Enabled=false;
|
||||
}else if(smessage.equals("echo on")) {
|
||||
serialCommandEcho_Enabled=true;
|
||||
}
|
||||
|
||||
if (serialCommandEcho_Enabled) { //Echo Command
|
||||
Serial.print("$"); Serial.println(message);
|
||||
}
|
||||
|
||||
//Handle Commands
|
||||
if(smessage.equals("test")) {
|
||||
Serial.println("OK");
|
||||
}else if(smessage.equals("ls")) {
|
||||
printFileListing(false);
|
||||
}else if(smessage.equals("ls -a")) {
|
||||
printFileListing(true);
|
||||
}else if(smessage.startsWith("cat")) {
|
||||
String _filename=smessage.substring(4);
|
||||
if (_filename.length()<3){ //if no filename given, use current log file
|
||||
_filename=getLogFilename();
|
||||
}
|
||||
printFile(_filename);
|
||||
}else if(smessage.startsWith("get")) {
|
||||
String _filename=smessage.substring(4);
|
||||
transferFile(_filename);
|
||||
}else if(smessage.startsWith("sizeof")) {
|
||||
String _filename=smessage.substring(7);
|
||||
printFilesize(_filename);
|
||||
}else if(smessage.startsWith("chunksize")) { //change chunksize for get command
|
||||
String _chunksizestring=smessage.substring(10);
|
||||
long _chunksize=_chunksizestring.toInt();
|
||||
if (_chunksize>0 && _chunksize<LONG_MAX) { //value ok
|
||||
chunksize=_chunksize;
|
||||
}else{
|
||||
Serial.println("Chunksize value out of range");
|
||||
}
|
||||
}else if(smessage.startsWith("rm")) {
|
||||
removeFile(smessage.substring(3));
|
||||
}else if(smessage.equals("log off")) {
|
||||
writeLogComment(loopmillis, "Datalogging disabled by serial command");
|
||||
datalogging=false;
|
||||
Serial.print("Log disabled: "); Serial.println(datalogging_filename);
|
||||
}else if(smessage.equals("log on")) {
|
||||
datalogging=true;
|
||||
writeLogComment(loopmillis, "Datalogging enabled by serial command");
|
||||
Serial.print("Log enabled: "); Serial.println(datalogging_filename);
|
||||
}else if(smessage.equals("show stats")) {
|
||||
Serial.print("overallTrip\t"); Serial.println(overallTrip);
|
||||
Serial.print("overallCurrentConsumed\t"); Serial.println(overallCurrentConsumed);
|
||||
Serial.print("overallWatthoursConsumed\t"); Serial.println(overallWatthoursConsumed);
|
||||
Serial.print("voltage\t"); Serial.println(getBatteryVoltage(escFront,escRear));
|
||||
}else if(smessage.equals("show sensors")) {
|
||||
Serial.print("loopmillis\t"); Serial.println(loopmillis);
|
||||
Serial.print("temp_ESCFront\t"); Serial.println(escFront.getFeedback_boardTemp());
|
||||
Serial.print("temp_ESCRear\t"); Serial.println(escRear.getFeedback_boardTemp());
|
||||
Serial.print("vbat_Front\t"); Serial.println(escFront.getFeedback_batVoltage());
|
||||
Serial.print("vbat_Rear\t"); Serial.println(escRear.getFeedback_batVoltage());
|
||||
Serial.print("throttle\t"); Serial.println(throttle_pos);
|
||||
Serial.print("brake\t"); Serial.println(brake_pos);
|
||||
Serial.print("trip_Front\t"); Serial.println(escFront.getTrip());
|
||||
Serial.print("trip_Rear\t"); Serial.println(escRear.getTrip());
|
||||
Serial.print("trip\t"); Serial.println(trip);
|
||||
Serial.print("currentConsumed_Front\t"); Serial.println(escFront.getCurrentConsumed(),3);
|
||||
Serial.print("currentConsumed_Rear\t"); Serial.println(escRear.getCurrentConsumed(),3);
|
||||
Serial.print("currentConsumed\t"); Serial.println(currentConsumed,3);
|
||||
Serial.print("watthoursConsumed\t"); Serial.println(watthoursConsumed,3);
|
||||
Serial.print("temp_Front\t"); Serial.println(temp_Front,3);
|
||||
Serial.print("temp_Rear\t"); Serial.println(temp_Rear,3);
|
||||
Serial.print("temp_Air\t"); Serial.println(temp_Air,3);
|
||||
Serial.print("looptime_duration_min\t"); Serial.println(looptime_duration_min);
|
||||
Serial.print("looptime_duration_max\t"); Serial.println(looptime_duration_max);
|
||||
}
|
||||
|
||||
message_pos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void printFileListing(bool pretty) {
|
||||
File root;
|
||||
root = SD.open("/");
|
||||
|
||||
if (pretty) {
|
||||
printDirectory(root, 0,"",true,false); //tabbed with file sizes
|
||||
}else{
|
||||
printDirectory(root, 0,"",false,true); //full paths without size
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printDirectory(File dir, int numTabs,String parent,bool printSize,bool printFullDirectoryNames) {
|
||||
|
||||
|
||||
while (true) {
|
||||
|
||||
File entry = dir.openNextFile();
|
||||
if (! entry) {
|
||||
// no more files
|
||||
break;
|
||||
}
|
||||
if (!printFullDirectoryNames) {
|
||||
for (uint8_t i = 0; i < numTabs; i++) {
|
||||
Serial.print('\t');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!entry.isDirectory() || !printFullDirectoryNames) {
|
||||
Serial.print(parent+entry.name());
|
||||
}
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
if (!printFullDirectoryNames) {
|
||||
Serial.println("/");
|
||||
}
|
||||
printDirectory(entry, numTabs + 1,parent+entry.name()+"/",printSize,printFullDirectoryNames);
|
||||
} else {
|
||||
if (printSize) {
|
||||
// files have sizes, directories do not
|
||||
Serial.print("\t\t");
|
||||
Serial.print(entry.size(), DEC);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
entry.close();
|
||||
}
|
||||
}
|
||||
|
||||
void printFilesize(String filename) {
|
||||
File dataFile = SD.open(filename.c_str(), FILE_READ);
|
||||
if (dataFile) {
|
||||
Serial.println(dataFile.size(), DEC);
|
||||
dataFile.close();
|
||||
}else{
|
||||
Serial.println('0');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void printFile(String filename) {
|
||||
|
||||
File dataFile = SD.open(filename.c_str(), FILE_READ);
|
||||
|
||||
|
||||
|
||||
// if the file is available, write to it:
|
||||
if (dataFile) {
|
||||
while (dataFile.available()) {
|
||||
Serial.write(dataFile.read());
|
||||
}
|
||||
dataFile.close();
|
||||
}
|
||||
// if the file isn't open, pop up an error:
|
||||
else {
|
||||
Serial.print("error opening "); Serial.println(filename);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void transferFile(String filename) {
|
||||
//similar to printFile, but with checksum and chunk based transfer
|
||||
|
||||
|
||||
|
||||
|
||||
File dataFile = SD.open(filename.c_str(), FILE_READ);
|
||||
|
||||
bool transmiterror=false;
|
||||
|
||||
// if the file is available, write to it:
|
||||
if (dataFile) {
|
||||
while (dataFile.available() && !transmiterror) {
|
||||
byte checksum=0;
|
||||
for (uint16_t i=0;i<chunksize;i++) {
|
||||
if (dataFile.available()) {
|
||||
byte b = dataFile.read();
|
||||
Serial.write(b);
|
||||
checksum+=b;
|
||||
}
|
||||
}
|
||||
int inByte=-1;
|
||||
while (inByte==-1) {
|
||||
if (Serial.available() > 0)
|
||||
{
|
||||
inByte = Serial.read();
|
||||
|
||||
if ((byte)inByte!=checksum){
|
||||
transmiterror=true; //exit
|
||||
Serial.println();
|
||||
Serial.println("TRANSMISSION ERROR WRONG CHECKSUM");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
dataFile.close();
|
||||
}
|
||||
// if the file isn't open, pop up an error:
|
||||
else {
|
||||
Serial.print("error opening "); Serial.println(filename);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void removeFile(String filename) {
|
||||
|
||||
SD.remove(filename.c_str());
|
||||
if (SD.exists(filename.c_str())) {
|
||||
Serial.println("File still exists");
|
||||
} else {
|
||||
Serial.println("OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
121
controller_teensy/include/rc.h
Normal file
121
controller_teensy/include/rc.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
#ifndef _RC_H_
|
||||
#define _RC_H_
|
||||
|
||||
|
||||
#define RC
|
||||
|
||||
#include <PulsePosition.h>
|
||||
PulsePositionInput ppmIn;
|
||||
|
||||
#define PPMREADPERIOD 20 //period for d4r-ii is 18ms
|
||||
static int count=0;
|
||||
|
||||
#define PIN_PPM 9
|
||||
|
||||
#define PPM_CHANNELS 8
|
||||
#define PPM_SAVE_MIN 950 //minimum allowed for valid data
|
||||
#define PPM_SAVE_MAX 2050 //maximum allowed for valid data
|
||||
#define PPM_MIN 1000
|
||||
#define PPM_MAX 2000
|
||||
#define PPM_MID 1500
|
||||
#define PPM_DEADBAND 5
|
||||
#define PPM_CHANNEL_THROTTLE 1
|
||||
#define PPM_CHANNEL_STEER 2
|
||||
#define PPM_CHANNEL_MODE 5
|
||||
float ppm[PPM_CHANNELS];
|
||||
|
||||
unsigned long ppm_count_success=0;
|
||||
unsigned long ppm_count_fail=0;
|
||||
|
||||
void initRC();
|
||||
void readPPM(unsigned long loopmillis);
|
||||
void printPPM();
|
||||
|
||||
int16_t getRCThrottle();
|
||||
int16_t getRCSteer();
|
||||
uint8_t getRCMode(uint8_t modes);
|
||||
|
||||
bool rc_fullcontrol_enabled=false; //full remote control. can be cancelled by button press
|
||||
bool rc_steer_enabled=false; //only rc steering
|
||||
|
||||
void initRC() {
|
||||
ppmIn.begin(PIN_PPM);
|
||||
}
|
||||
|
||||
void readPPM(unsigned long loopmillis) {
|
||||
int ppm_num = ppmIn.available();
|
||||
if (ppm_num > 0) {
|
||||
bool ppm_ok=true;
|
||||
float new_ppm[PPM_CHANNELS];
|
||||
if (ppm_num != PPM_CHANNELS) {
|
||||
ppm_ok=false;
|
||||
}else{
|
||||
for (int i=1; i <= ppm_num; i++) {
|
||||
float val=ppmIn.read(i);
|
||||
new_ppm[i-1]=val;
|
||||
if (val<PPM_SAVE_MIN || val>PPM_SAVE_MAX) {
|
||||
ppm_ok=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ppm_ok) {
|
||||
ppm_count_success+=1;
|
||||
std::copy(std::begin(new_ppm), std::end(new_ppm), std::begin(ppm));
|
||||
}else{
|
||||
ppm_count_fail+=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float getPPMSuccessrate() {
|
||||
float rate=ppm_count_success*1.0/(ppm_count_success+ppm_count_fail);
|
||||
if (ppm_count_success+ppm_count_fail>500) {
|
||||
ppm_count_success=0;
|
||||
ppm_count_fail=0;
|
||||
}
|
||||
return rate;
|
||||
}
|
||||
|
||||
//Return value 0 - 1000
|
||||
int16_t getRCThrottle() {
|
||||
return constrain(map(ppm[PPM_CHANNEL_THROTTLE-1],PPM_MID+PPM_DEADBAND,PPM_MAX,0,1000), 0,1000);
|
||||
}
|
||||
|
||||
int16_t getRCBrake() {
|
||||
return constrain(map(ppm[PPM_CHANNEL_THROTTLE-1],PPM_MID-PPM_DEADBAND,PPM_MIN,0,1000), 0,1000);
|
||||
}
|
||||
|
||||
//Return value -1000 - 1000
|
||||
int16_t getRCSteer() {
|
||||
if (ppm[PPM_CHANNEL_STEER-1]>PPM_MID+PPM_DEADBAND){
|
||||
return constrain(map(ppm[PPM_CHANNEL_STEER-1],PPM_MID+PPM_DEADBAND,PPM_MAX,0,1000), 0,1000);
|
||||
}else if (ppm[PPM_CHANNEL_STEER-1]<PPM_MID-PPM_DEADBAND){
|
||||
return constrain(map(ppm[PPM_CHANNEL_STEER-1],PPM_MID-PPM_DEADBAND,PPM_MIN,0,-1000), -1000,0);
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Return descrete value for equidistant ranges. modes = number of ranges.
|
||||
uint8_t getRCMode(uint8_t modes) {
|
||||
float v=constrain(map(ppm[PPM_CHANNEL_MODE-1],PPM_MIN,PPM_MAX,0.0,1.0), 0.0,0.999);
|
||||
return uint8_t(v*modes);
|
||||
}
|
||||
|
||||
|
||||
void printPPM(unsigned long loopmillis){
|
||||
|
||||
count = count + 1;
|
||||
Serial.print("ms :");
|
||||
Serial.print(count);
|
||||
Serial.print(" : ");
|
||||
for (int i=1; i <= PPM_CHANNELS; i++) {
|
||||
Serial.print(ppm[i-1]);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -4,11 +4,13 @@
|
|||
#include <OneWire.h>
|
||||
#include <DallasTemperature.h>
|
||||
|
||||
//#define SEARCH_DEVICES
|
||||
|
||||
DeviceAddress thermometerESCFront={0x28,0xFF,0x64,0x0E,0x77,0xB0,0xAB,0x4B}; //IC with one marking 28FF640E77B0AB4B
|
||||
float temp_ESCFront;
|
||||
DeviceAddress thermometerESCRear={0x28,0xFF,0x64,0x0E,0x76,0x5D,0x86,0xC2}; //IC with two markings
|
||||
float temp_ESCRear;
|
||||
|
||||
DeviceAddress thermometerFront={0x28,0xFF,0x64,0x0E,0x77,0xB0,0xAB,0x4B}; //IC with one marking 28FF640E77B0AB4B
|
||||
float temp_Front;
|
||||
DeviceAddress thermometerRear={0x28,0xFF,0x64,0x0E,0x76,0x5D,0x86,0xC2}; //IC with two markings
|
||||
float temp_Rear;
|
||||
DeviceAddress thermometerAir={0x28,0xFF,0x64,0x0E,0x74,0x7E,0xFE,0x23}; //IC with three markings 28FF640E747EFE23
|
||||
float temp_Air;
|
||||
|
||||
|
@ -29,20 +31,15 @@ void printAddress(DeviceAddress deviceAddress);
|
|||
void initTemperature() {
|
||||
|
||||
sensors.begin();
|
||||
delay(1000);
|
||||
|
||||
//Just search for devices. Only needed when connecting a new sensor to find the address
|
||||
#ifdef SEARCH_DEVICES
|
||||
|
||||
Serial.print("Locating 1Wire devices...");
|
||||
Serial.print("Found ");
|
||||
Serial.print(sensors.getDeviceCount(), DEC);
|
||||
Serial.println(" devices.");
|
||||
|
||||
delay(1000);
|
||||
|
||||
delay(1000);
|
||||
|
||||
|
||||
//Just search for devices. Only needed when connecting a new sensor to find the address
|
||||
oneWire.reset_search();
|
||||
|
||||
for (uint8_t i=0;i<sensors.getDeviceCount();i++){
|
||||
|
@ -58,8 +55,9 @@ void initTemperature() {
|
|||
}
|
||||
|
||||
delay(1000);
|
||||
#endif
|
||||
|
||||
//sensors.setResolution(thermometerReservoir, TEMPERATURE_PRECISION);
|
||||
//sensors.setResolution(thermometerESCFront, TEMPERATURE_PRECISION);
|
||||
|
||||
|
||||
}
|
||||
|
@ -86,8 +84,8 @@ bool temperatureLoop(unsigned long loopmillis) {
|
|||
if (sensors.isConversionComplete()) {
|
||||
flag_requestTemperatures=false;
|
||||
last_read_ds18b20=loopmillis;
|
||||
temp_ESCFront= sensors.getTempC(thermometerESCFront); //This takes ~12.5ms
|
||||
temp_ESCRear= sensors.getTempC(thermometerESCRear);
|
||||
temp_Front= sensors.getTempC(thermometerFront); //This takes ~12.5ms
|
||||
temp_Rear= sensors.getTempC(thermometerRear);
|
||||
temp_Air= sensors.getTempC(thermometerAir);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 150ce61f9f8d8c013f2fca424ec2976c3582d403
|
||||
Subproject commit 0cf2df74e186bc5c6dd60cecedb3a865f5b9d467
|
|
@ -26,6 +26,7 @@ lib_deps =
|
|||
adafruit/Adafruit SSD1306@^2.5.7
|
||||
https://github.com/adafruit/Adafruit_NeoPixel
|
||||
https://github.com/milesburton/Arduino-Temperature-Control-Library/
|
||||
https://github.com/PaulStoffregen/PulsePosition
|
||||
|
||||
|
||||
[env:teensy31]
|
||||
|
|
|
@ -16,15 +16,18 @@
|
|||
#include "led.h"
|
||||
#include "temperature.h"
|
||||
|
||||
//#include "comms.h"
|
||||
|
||||
String getLogFilename();
|
||||
bool getDatalogging();
|
||||
#include "display.h"
|
||||
#include "logging.h"
|
||||
#include "rc.h"
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
|
||||
|
||||
//#define CALIBRATION_THROTTLE_CURVE //uncomment to enable throttleA and B serial output on button press
|
||||
|
||||
|
||||
|
||||
|
@ -48,7 +51,7 @@ void readADC();
|
|||
void failChecks();
|
||||
//void sendCMD();
|
||||
void calculateSetSpeed(unsigned long timediff);
|
||||
void checkLog();
|
||||
|
||||
|
||||
void leds();
|
||||
|
||||
|
@ -69,11 +72,25 @@ void setup()
|
|||
|
||||
Serial1.begin(SERIAL_LOG_BAUD); //TX1=1, RX1=0
|
||||
|
||||
//Serial2.begin(SERIAL_CONTROL_BAUD); //control, TX2=10, RX2=9
|
||||
//Serial3.begin(SERIAL_CONTROL_BAUD); //control, TX3=8, RX3=7
|
||||
|
||||
|
||||
pinMode(PIN_PWRBUTTON, INPUT_PULLUP); //Pressed=High
|
||||
|
||||
datalogging=false; //disable logging when connected via usb to not clutter up sd card
|
||||
Serial.print("PWRBUTTON ");
|
||||
for (uint8_t i=0;i<10;i++) { //check a few times
|
||||
if (!digitalRead(PIN_PWRBUTTON)) { //button is not pressed during startup means teensy is powered externally (usb)
|
||||
Serial.print(".");
|
||||
delay(100); //give more time to disable logging
|
||||
}else{
|
||||
datalogging=true; //button presse at least once recognized. enable logging
|
||||
Serial.print("X");
|
||||
}
|
||||
}
|
||||
if (!datalogging){
|
||||
Serial.println(" not pressed. Logging disabled!");
|
||||
}else{
|
||||
Serial.println(" Pressed. Logging enabled");
|
||||
}
|
||||
|
||||
pinMode(PIN_LED_START, OUTPUT); //Active High
|
||||
|
||||
|
@ -90,19 +107,21 @@ void setup()
|
|||
led_testLEDSBlocking();
|
||||
|
||||
|
||||
delay(2000);
|
||||
delay(100);
|
||||
Serial.println("Init Functions");
|
||||
led_simpeProgress(0,1);
|
||||
|
||||
bool initResult=false;
|
||||
|
||||
initResult=display_init();
|
||||
if (!initResult) {
|
||||
writeLogComment((unsigned long)millis(), "SSD1306 allocation failed");
|
||||
}
|
||||
led_simpeProgress(1,initResult);
|
||||
|
||||
|
||||
|
||||
initResult=initLogging();
|
||||
led_simpeProgress(2,initResult);
|
||||
led_simpeProgress(2,(initResult ? (datalogging ? 1:2):0)); //0=sd card fail, 1=sd ok and logging, 2(warn)=sd ok and logging off
|
||||
|
||||
|
||||
|
||||
|
@ -127,7 +146,6 @@ void setup()
|
|||
// also set ADSREADPERIOD to at least the read interval
|
||||
ADS.requestADC(0); //Start requesting a channel
|
||||
led_simpeProgress(6,true);
|
||||
writeLogComment((unsigned long)millis(), "ADS1115 Initialized");
|
||||
}
|
||||
delay(10);
|
||||
for (uint8_t i=0;i<4;i++){ //read all channels once to have adc readings ready in first loop (to prevent premature failsafe)
|
||||
|
@ -139,6 +157,8 @@ void setup()
|
|||
setSyncProvider(getTeensy3Time); //See https://www.pjrc.com/teensy/td_libs_Time.html#teensy3
|
||||
if (timeStatus()!= timeSet) {
|
||||
Serial.println("Unable to sync with the RTC");
|
||||
|
||||
writeLogComment((unsigned long)millis(), "Unable to sync with the RTC");
|
||||
led_simpeProgress(7,false);
|
||||
} else {
|
||||
Serial.println("RTC has set the system time");
|
||||
|
@ -146,7 +166,7 @@ void setup()
|
|||
}
|
||||
|
||||
|
||||
if (datalogging) { //sd init was successful
|
||||
if (sdcard_available) { //sd init was successful
|
||||
initResult=loadTripSD();
|
||||
}else{
|
||||
initResult=false;
|
||||
|
@ -156,13 +176,18 @@ void setup()
|
|||
|
||||
initTemperature();
|
||||
led_simpeProgress(9,true);
|
||||
|
||||
initRC();
|
||||
|
||||
led_simpeProgress(10,true);
|
||||
|
||||
|
||||
|
||||
writeLogComment(millis(), "Setup Finished");
|
||||
led_simpeProgress(15,true);
|
||||
|
||||
led_simpleProgressWait(); //wait longer if any errors were displayed with led_simpeProgress()
|
||||
|
||||
Serial.println("Ready");
|
||||
}
|
||||
|
||||
|
||||
|
@ -173,46 +198,6 @@ void loop() {
|
|||
|
||||
loopmillis=millis(); //read millis for this cycle
|
||||
|
||||
|
||||
|
||||
/*
|
||||
// ____ Debugging pending serial byted for feedback
|
||||
static int s2availmax=0;
|
||||
int _a2=Serial2.available();
|
||||
if (_a2>s2availmax) {
|
||||
s2availmax=_a2;
|
||||
//Serial.print("new s2availmax"); Serial.println(s2availmax);
|
||||
String _text="Serial2 Bytes Available Max=";
|
||||
_text+=s2availmax;
|
||||
writeLogComment(Serial1,loopmillis, _text);
|
||||
}
|
||||
|
||||
static int s3availmax=0;
|
||||
int _a3=Serial3.available();
|
||||
if (_a3>s3availmax) {
|
||||
s3availmax=_a3;
|
||||
//Serial.print("new s3availmax"); Serial.println(s3availmax);
|
||||
String _text="Serial3 Bytes Available Max=";
|
||||
_text+=s3availmax;
|
||||
writeLogComment(Serial1,loopmillis, _text);
|
||||
}
|
||||
// ----- End of debug
|
||||
|
||||
|
||||
|
||||
bool newData2=ReceiveSerial(SerialcomFront,FeedbackFront, NewFeedbackFront, Serial2);
|
||||
bool newData3=ReceiveSerial(SerialcomRear,FeedbackRear, NewFeedbackRear, Serial3);
|
||||
//Max (40) or 22 available/pending bytes
|
||||
|
||||
if (newData2) {
|
||||
updateMotorparams(motorparamsFront,FeedbackFront,loopmillis);
|
||||
}
|
||||
if (newData3) {
|
||||
updateMotorparams(motorparamsRear,FeedbackRear,loopmillis);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -240,6 +225,13 @@ void loop() {
|
|||
readADSButtons();
|
||||
}
|
||||
|
||||
|
||||
static unsigned long last_ppmread=0;
|
||||
if (loopmillis - last_ppmread > PPMREADPERIOD) { //read digital input states
|
||||
last_ppmread=loopmillis;
|
||||
readPPM(loopmillis);
|
||||
}
|
||||
|
||||
|
||||
failChecks();
|
||||
|
||||
|
@ -253,14 +245,17 @@ void loop() {
|
|||
|
||||
max_filtered_currentAll=max(max_filtered_currentAll,filtered_currentAll);
|
||||
min_filtered_currentAll=min(min_filtered_currentAll,filtered_currentAll);
|
||||
max_filtered_wattAll=max(max_filtered_wattAll,filtered_currentAll*(escFront.getFeedback_batVoltage()+escRear.getFeedback_batVoltage())/2.0);
|
||||
min_filtered_wattAll=min(min_filtered_wattAll,filtered_currentAll*(escFront.getFeedback_batVoltage()+escRear.getFeedback_batVoltage())/2.0);
|
||||
float _meanVoltage=(escFront.getFeedback_batVoltage()+escRear.getFeedback_batVoltage())/2.0;
|
||||
max_filtered_wattAll=max(max_filtered_wattAll,filtered_currentAll*_meanVoltage);
|
||||
min_filtered_wattAll=min(min_filtered_wattAll,filtered_currentAll*_meanVoltage);
|
||||
min_voltage=min(min_voltage,_meanVoltage);
|
||||
max_meanSpeed=max(max_meanSpeed,(escFront.getMeanSpeed()+escRear.getMeanSpeed())/2);
|
||||
if (!armed) { //reset statistics if disarmed
|
||||
max_filtered_currentAll=0;
|
||||
min_filtered_currentAll=0;
|
||||
max_filtered_wattAll=0;
|
||||
min_filtered_wattAll=0;
|
||||
min_voltage=99;
|
||||
max_meanSpeed=0;
|
||||
}
|
||||
}
|
||||
|
@ -288,32 +283,8 @@ void loop() {
|
|||
last_statsupdate=loopmillis;
|
||||
}
|
||||
|
||||
/* TODO: remove this if, because everything contained in esc.update()
|
||||
if (loopmillis - last_send > SENDPERIOD) { //Calculate motor stuff and send to motor controllers
|
||||
last_send=loopmillis;
|
||||
//sendCMD();
|
||||
|
||||
|
||||
|
||||
//Update speed and trip
|
||||
float _meanRPM=(FeedbackFront.speedL_meas-FeedbackFront.speedR_meas+FeedbackRear.speedL_meas-FeedbackRear.speedR_meas)/4.0;
|
||||
meanSpeedms=_meanRPM*wheelcircumference/60.0; // Units: 1/min * m / 60s
|
||||
trip+=abs(meanSpeedms)* (SENDPERIOD/1000.0);
|
||||
|
||||
//mah consumed
|
||||
currentConsumed += (motorparamsFront.filtered_curL+motorparamsFront.filtered_curR+motorparamsRear.filtered_curL+motorparamsRear.filtered_curR)* (SENDPERIOD/1000.0)/3600.0; //amp hours
|
||||
}
|
||||
*/
|
||||
|
||||
//If needed write log to serial port
|
||||
//checkLog(); //TODO remove
|
||||
loggingLoop(loopmillis,escFront,escRear);
|
||||
if (!armed && !statswritten) { //write stats only once when disarmed
|
||||
statswritten=true;
|
||||
writeTrip(loopmillis,escFront,escRear);
|
||||
}
|
||||
if (statswritten && armed) {
|
||||
statswritten=false;
|
||||
}
|
||||
|
||||
leds();
|
||||
led_update(loopmillis,escFront,escRear); //ws2812 led ring
|
||||
|
@ -340,11 +311,11 @@ void loop() {
|
|||
last_fan_update=loopmillis;
|
||||
boolean fanstatus=digitalRead(PIN_FAN);
|
||||
//float temp=max(escFront.getFeedback_boardTemp(),escRear.getFeedback_boardTemp());
|
||||
float temp=max(temp_ESCFront,temp_ESCRear);
|
||||
if (temp_ESCFront==DEVICE_DISCONNECTED_C || temp_ESCRear==DEVICE_DISCONNECTED_C ) { //temperature error
|
||||
float temp=max(temp_Front,temp_Rear);
|
||||
if (temp_Front==DEVICE_DISCONNECTED_C || temp_Rear==DEVICE_DISCONNECTED_C ) { //temperature error
|
||||
digitalWrite(PIN_FAN,HIGH); //force fan on
|
||||
|
||||
}else{ //normal temperature control
|
||||
}else{ //normal temperature control_currentIncrease
|
||||
|
||||
if (!fanstatus) { //fan is off
|
||||
if (temp>=fan_turn_on_temp){
|
||||
|
@ -359,8 +330,24 @@ void loop() {
|
|||
|
||||
|
||||
}
|
||||
|
||||
|
||||
serialCommandLoop(loopmillis,escFront,escRear);
|
||||
|
||||
looptime_duration=max(looptime_duration,millis()-loopmillis);
|
||||
|
||||
//Logging
|
||||
loggingLoop(loopmillis,escFront,escRear);
|
||||
if (!armed && !statswritten) { //write stats only once when disarmed
|
||||
statswritten=true;
|
||||
writeTrip(loopmillis,escFront,escRear);
|
||||
}
|
||||
if (statswritten && armed) {
|
||||
statswritten=false;
|
||||
}
|
||||
|
||||
|
||||
looptime_duration_min=min(looptime_duration_min,millis()-loopmillis);
|
||||
looptime_duration_max=max(looptime_duration_max,millis()-loopmillis);
|
||||
|
||||
}
|
||||
|
||||
|
@ -408,24 +395,9 @@ void readADS() { //sequentially read ads and write to variable
|
|||
|
||||
|
||||
void readADC() {
|
||||
|
||||
//Serial.print(ads_throttle_A_raw); Serial.print('\t');
|
||||
//Serial.print(ads_throttle_B_raw); Serial.print('\t');
|
||||
//Serial.print(ads_brake_raw); Serial.print('\t');
|
||||
//Serial.print(ads_control_raw); Serial.println();
|
||||
//throttle_raw = (ads_throttle_A_raw+ads_throttle_B_raw)/2.0*THROTTLE_ADC_FILTER + throttle_raw*(1-THROTTLE_ADC_FILTER); //apply filter
|
||||
|
||||
throttle_rawA=ads_throttle_A_raw;
|
||||
throttle_rawB=ads_throttle_B_raw;
|
||||
|
||||
|
||||
//maps throttle curve to be linear
|
||||
//throttle_pos=max(0,min(1000,linearizeThrottle(throttle_raw))); //map and constrain
|
||||
throttle_posA=max(0,min(1000, linearizeThrottle(ads_throttle_A_raw, throttleCurvePerMM_A, sizeof(throttleCurvePerMM_A)/sizeof(throttleCurvePerMM_A[0]), throttleCurvePerMM_A_Descending ) )); //map and constrain
|
||||
throttle_posB=max(0,min(1000, linearizeThrottle(ads_throttle_B_raw, throttleCurvePerMM_B, sizeof(throttleCurvePerMM_B)/sizeof(throttleCurvePerMM_B[0]), throttleCurvePerMM_B_Descending ) )); //map and constrain
|
||||
|
||||
//Serial.print(throttle_posA); Serial.print('\t');
|
||||
//Serial.print(throttle_posB); Serial.print('\t');
|
||||
throttle_posA=max(0,min(1000, linearizeThrottle(ads_throttle_A_raw, throttleCurvePerMM_A, sizeof(throttleCurvePerMM_A)/sizeof(throttleCurvePerMM_A[0]), throttleCurvePerMM_A_Descending ) )); //linearize and constrain (linear function already constrains)
|
||||
throttle_posB=max(0,min(1000, linearizeThrottle(ads_throttle_B_raw, throttleCurvePerMM_B, sizeof(throttleCurvePerMM_B)/sizeof(throttleCurvePerMM_B[0]), throttleCurvePerMM_B_Descending ) )); //linearize and constrain (linear function already constrains
|
||||
|
||||
|
||||
int16_t throttle_posMean = (throttle_posA+throttle_posB)/2.0;
|
||||
|
||||
|
@ -433,20 +405,13 @@ void readADC() {
|
|||
throttle_pos = throttle_posMean*THROTTLE_ADC_FILTER + throttle_pos*(1-THROTTLE_ADC_FILTER); //apply filter
|
||||
|
||||
|
||||
brake_raw=ads_brake_raw;
|
||||
brake_pos=max(0,min(1000,map(brake_raw,calib_brake_min,calib_brake_max,0,1000))); //map and constrain
|
||||
brake_linear=map(ads_brake_raw,calib_brake_min,calib_brake_max,0,1000);
|
||||
brake_pos=max(0,min(1000,brake_linear)); //map and constrain
|
||||
//brake_pos = (int16_t)(pow((brake_pos/1000.0),2)*1000);
|
||||
|
||||
|
||||
|
||||
if (throttle_pos>0 || ((escFront.getMeanSpeed()+escRear.getMeanSpeed())/2.0) >0.5 || (!reverse_enabled && brake_pos>0)) { //reset idle time on these conditions (disables reverse driving)
|
||||
last_notidle=loopmillis;
|
||||
reverse_enabled=false;
|
||||
}
|
||||
|
||||
if (loopmillis-last_notidle > REVERSE_ENABLE_TIME) {
|
||||
reverse_enabled=true;
|
||||
}
|
||||
|
||||
int16_t throttlebreak_pos = throttle_pos-brake_pos*2; //reduce throttle_when applying brake
|
||||
throttle_pos=constrain(throttlebreak_pos,0,1000);
|
||||
|
@ -483,6 +448,7 @@ void failChecks() {
|
|||
if ((ads_throttle_A_raw >= failsafe_throttle_min_A) & (ads_throttle_A_raw <= failsafe_throttle_max_A) & (ads_throttle_B_raw >= failsafe_throttle_min_B) & (ads_throttle_B_raw <= failsafe_throttle_max_B)) { //inside safe range (to check if wire got disconnected)
|
||||
throttle_ok_time=loopmillis;
|
||||
}
|
||||
|
||||
if (loopmillis>throttle_ok_time+ADC_OUTOFRANGE_TIME) { //not ok for too long
|
||||
if (!error_throttle_outofrange) {
|
||||
error_throttle_outofrange=true;
|
||||
|
@ -491,10 +457,12 @@ void failChecks() {
|
|||
//Serial.print("Error Throttle ADC Out of Range="); Serial.println(throttle_raw);
|
||||
}
|
||||
|
||||
|
||||
static unsigned long throttlediff_ok_time=0;
|
||||
if (abs(throttle_posA-throttle_posB) <= failsafe_throttle_maxDiff) { //inside safe range (to check if wire got disconnected)
|
||||
throttlediff_ok_time=loopmillis;
|
||||
}
|
||||
#ifndef CALIBRATION_THROTTLE_CURVE //do not check if throttle calibration enabled
|
||||
if (loopmillis>throttlediff_ok_time+ADC_DIFFHIGH_TIME) { //not ok for too long
|
||||
if (!error_throttle_difftoohigh) {
|
||||
error_throttle_difftoohigh=true;
|
||||
|
@ -502,16 +470,17 @@ void failChecks() {
|
|||
}
|
||||
//Serial.print("Error Throttle ADC Out of Range="); Serial.println(throttle_raw);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static unsigned long brake_ok_time=0;
|
||||
if ((brake_raw >= failsafe_brake_min) & (brake_raw <= failsafe_brake_max)) { //outside safe range. maybe wire got disconnected
|
||||
if ((ads_brake_raw >= failsafe_brake_min) & (ads_brake_raw <= failsafe_brake_max)) { //outside safe range. maybe wire got disconnected
|
||||
brake_ok_time=loopmillis;
|
||||
}
|
||||
if (loopmillis>brake_ok_time+ADC_OUTOFRANGE_TIME) { //not ok for too long
|
||||
if(!error_brake_outofrange) {
|
||||
error_brake_outofrange=true;
|
||||
writeLogComment(loopmillis, "Error Brake ADC Out of Range. ADC="+(String)brake_raw);
|
||||
writeLogComment(loopmillis, "Error Brake ADC Out of Range. ADC="+(String)ads_brake_raw);
|
||||
}
|
||||
//Serial.print("Error Brake ADC Out of Range="); Serial.println(brake_raw);
|
||||
}
|
||||
|
@ -540,9 +509,39 @@ void failChecks() {
|
|||
void calculateSetSpeed(unsigned long timediff){
|
||||
|
||||
int16_t adjusted_throttle_pos=constrain(throttle_pos*(throttle_max/1000.0),0,throttle_max);
|
||||
int16_t brake_pos_linear=brake_pos;
|
||||
int16_t brake_pos_expo = (int16_t)(pow((brake_pos_linear/1000.0),2)*1000);
|
||||
|
||||
int16_t brake_pos_expo = (int16_t)(pow((brake_pos/1000.0),2)*1000);
|
||||
|
||||
|
||||
#ifdef RC
|
||||
if (throttle_pos>0 || brake_pos>0) { //touch any pedal to cancel rc fullcontrol mode
|
||||
rc_fullcontrol_enabled=false;
|
||||
}
|
||||
|
||||
if (rc_fullcontrol_enabled) {
|
||||
int16_t rcthrottle_pos=getRCThrottle();
|
||||
int16_t rcbrake_pos=getRCBrake();
|
||||
|
||||
|
||||
adjusted_throttle_pos=constrain(rcthrottle_pos*(throttle_max/1000.0),0,throttle_max); //overwrite with rc values
|
||||
brake_pos_linear=rcbrake_pos;
|
||||
brake_pos_expo = (int16_t)(pow((brake_pos_linear/1000.0),2)*1000);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//Reverse Enable
|
||||
if (throttle_pos>0 || ((escFront.getMeanSpeed()+escRear.getMeanSpeed())/2.0) >0.5 || (!reverse_enabled && brake_pos_linear>0)) { //reset idle time on these conditions (disables reverse driving)
|
||||
last_notidle=loopmillis;
|
||||
reverse_enabled=false;
|
||||
}
|
||||
if (loopmillis-last_notidle > REVERSE_ENABLE_TIME) {
|
||||
reverse_enabled=true;
|
||||
}
|
||||
|
||||
|
||||
//Throttle Management
|
||||
float brakepedal_current_multiplier=startbrakecurrent/1000.0; //how much breaking (in Ampere) for unit of brake_pos (0<=brake_pos<=1000)
|
||||
|
||||
int16_t cmdreduce_constant=map(brake_pos_expo,0,1000,0,(int16_t)(brake_cmdreduce_proportional*timediff/1000)); //reduce cmd value every cycle
|
||||
|
@ -564,27 +563,157 @@ void calculateSetSpeed(unsigned long timediff){
|
|||
|
||||
}
|
||||
|
||||
//acceleration
|
||||
cmd_send += constrain(adjusted_throttle_pos-cmd_send,0,(int16_t)(max_acceleration_rate*(timediff/1000.0)) ); //if throttle higher than last applied value, apply throttle directly
|
||||
// ## Acceleration
|
||||
cmd_send += constrain(adjusted_throttle_pos-cmd_send,0,(int16_t)(max_acceleration_rate*(timediff/1000.0)) ); //if throttle higher than last applied value, apply throttle directly with rate limit
|
||||
|
||||
cmd_send=constrain(cmd_send,0,throttle_max);
|
||||
|
||||
last_cmd_send=cmd_send;
|
||||
|
||||
int16_t cmd_send_toMotor=constrain(cmd_send* (1.0-(brake_pos*0.5/1000.0) ) ,0,throttle_max); //brake "ducking"
|
||||
int16_t cmd_send_toMotor_FL=0;
|
||||
int16_t cmd_send_toMotor_FR=0;
|
||||
int16_t cmd_send_toMotor_RL=0;
|
||||
int16_t cmd_send_toMotor_RR=0;
|
||||
int16_t _cmd_send_toMotor=constrain(cmd_send* (1.0-(brake_pos_expo*0.5/1000.0) ) ,0,throttle_max); //brake "ducking"
|
||||
|
||||
|
||||
if (reverse_enabled) {
|
||||
cmd_send_toMotor-=brake_pos*reverse_speed;
|
||||
|
||||
cmd_send_toMotor_FL=_cmd_send_toMotor;
|
||||
cmd_send_toMotor_FR=_cmd_send_toMotor;
|
||||
cmd_send_toMotor_RL=_cmd_send_toMotor;
|
||||
cmd_send_toMotor_RR=_cmd_send_toMotor;
|
||||
|
||||
#ifdef RC
|
||||
int16_t differential_steering_max=200;
|
||||
|
||||
#define RC_STEER_ENABLE_WAITTIME 1000/SENDPERIOD*2; //in cycles. every SENDPERIOD
|
||||
static uint16_t rc_steer_enable_wait=0; //give some time to release buttons after arming with rc mode to not cancel immediately
|
||||
if (rc_steer_enabled) {
|
||||
if (rc_steer_enable_wait>0) {
|
||||
rc_steer_enable_wait--;
|
||||
}else{ //allow control when counter reached 0
|
||||
if (control_buttonA || control_buttonB) { //cancel rc modes by button press
|
||||
rc_fullcontrol_enabled=false;
|
||||
rc_steer_enabled=false;
|
||||
}
|
||||
float rcsteer=getRCSteer()/1000.0;
|
||||
cmd_send_toMotor_FL+=rcsteer*differential_steering_max;
|
||||
cmd_send_toMotor_FR-=rcsteer*differential_steering_max;
|
||||
}
|
||||
}else{
|
||||
rc_steer_enable_wait=RC_STEER_ENABLE_WAITTIME;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef DRIVING_TANKSTEERING
|
||||
// ## Experimental Tank steering
|
||||
/* Notes from Drivetest 20240722
|
||||
When driving slow and pressing button steering wheel is turned more violently.
|
||||
When driving faster (>10km/h) steering wheel is not forced as strong, but bobbycar turns better around itself.
|
||||
As cmd increase in higher ranges is more pronounces in motor torque, the same tanksteering_max_speed=200 is way too strong when driving >20km/h, but okay when driving <10km/h.
|
||||
Disabled this function for now, because if button press is triggered erroneously during fast driving it could be dangerous. Steering manually against it is not possible.
|
||||
*/
|
||||
static float tanksteering_differential=0; //to ramp up slowly. value between -1.0 and 1.0
|
||||
//Parameters:
|
||||
int16_t tanksteering_max_speed=200;
|
||||
float tanksteering_rate_increase=2.0; //increase units per second
|
||||
float tanksteering_rate_decrease=3.0; //decrease units per second
|
||||
|
||||
if (control_buttonA && !control_buttonB && !reverse_enabled && throttle_pos>0) { //Right button (A) only. and throttle touched
|
||||
tanksteering_differential+=tanksteering_rate_increase*(timediff/1000.0);
|
||||
tanksteering_differential=constrain(tanksteering_differential,-1.0,1.0); //constrain between 0 and 1
|
||||
}else if(control_buttonB && !control_buttonA && !reverse_enabled && throttle_pos>0) { //Left button (B) only. and throttle touched
|
||||
tanksteering_differential-=tanksteering_rate_increase*(timediff/1000.0);
|
||||
tanksteering_differential=constrain(tanksteering_differential,-1.0,1.0); //constrain between 0 and 1
|
||||
}else{ //buttons released
|
||||
if(tanksteering_differential>0) {
|
||||
tanksteering_differential-=tanksteering_rate_decrease*(timediff/1000.0);
|
||||
}else if(tanksteering_differential<0){
|
||||
tanksteering_differential+=tanksteering_rate_decrease*(timediff/1000.0);
|
||||
}
|
||||
tanksteering_differential=constrain(tanksteering_differential,-1.0,1.0); //constrain between 0 and 1
|
||||
}
|
||||
|
||||
|
||||
cmd_send_toMotor_FL+=tanksteering_differential*tanksteering_max_speed;
|
||||
cmd_send_toMotor_FR-=tanksteering_differential*tanksteering_max_speed;
|
||||
cmd_send_toMotor_RL+=tanksteering_differential*tanksteering_max_speed;
|
||||
cmd_send_toMotor_RR-=tanksteering_differential*tanksteering_max_speed;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// ## Braking, Reversing and Standstill movements below here ##
|
||||
/*
|
||||
if (reverse_enabled) { //backwards driving not prohibited
|
||||
_cmd_send_toMotor-=brake_pos_linear*reverse_speed;
|
||||
|
||||
cmd_send_toMotor_FL=_cmd_send_toMotor;
|
||||
cmd_send_toMotor_FR=_cmd_send_toMotor;
|
||||
cmd_send_toMotor_RL=_cmd_send_toMotor;
|
||||
cmd_send_toMotor_RR=_cmd_send_toMotor;
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
float steeringdifferential_speed=0.4; //Speed for turning the steering wheel by differtially driving the front wheels
|
||||
|
||||
if (reverse_enabled) { //backwards driving not prohibited
|
||||
static bool tanksteering_prohibit_left=false;
|
||||
static bool tanksteering_prohibit_right=false;
|
||||
static bool prohibit_reverse=false;
|
||||
|
||||
if (control_buttonA && !control_buttonB) { //Right button (A) only
|
||||
tanksteering_prohibit_left=true;
|
||||
prohibit_reverse=true;
|
||||
}else if(control_buttonB && !control_buttonA) {//Left button (B) only
|
||||
tanksteering_prohibit_right=true;
|
||||
prohibit_reverse=true;
|
||||
}else if(!control_buttonA && !control_buttonB){ //no button pressed
|
||||
tanksteering_prohibit_left=true;
|
||||
tanksteering_prohibit_right=true;
|
||||
if (throttle_pos<=0 && brake_pos_linear<=0) {//levers released
|
||||
tanksteering_prohibit_left=false;
|
||||
tanksteering_prohibit_right=false;
|
||||
prohibit_reverse=false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tanksteering_prohibit_right && tanksteering_prohibit_left && prohibit_reverse) { //Right Tanksteering
|
||||
cmd_send_toMotor_FL+=brake_pos_linear*steeringdifferential_speed;
|
||||
cmd_send_toMotor_FR-=brake_pos_linear*steeringdifferential_speed;
|
||||
cmd_send_toMotor_RL+=brake_pos_linear*steeringdifferential_speed;
|
||||
cmd_send_toMotor_RR-=brake_pos_linear*steeringdifferential_speed;
|
||||
}else if(tanksteering_prohibit_right && !tanksteering_prohibit_left && prohibit_reverse) { //Left Tanksteering
|
||||
cmd_send_toMotor_FL-=brake_pos_linear*steeringdifferential_speed;
|
||||
cmd_send_toMotor_FR+=brake_pos_linear*steeringdifferential_speed;
|
||||
cmd_send_toMotor_RL-=brake_pos_linear*steeringdifferential_speed;
|
||||
cmd_send_toMotor_RR+=brake_pos_linear*steeringdifferential_speed;
|
||||
}else if(tanksteering_prohibit_right && tanksteering_prohibit_left && !prohibit_reverse){ //no button on steering wheel pressed, drive backwards
|
||||
int16_t cmd_send_brake=brake_pos_linear*reverse_speed;
|
||||
|
||||
cmd_send_toMotor_FL-=cmd_send_brake;
|
||||
cmd_send_toMotor_FR-=cmd_send_brake;
|
||||
cmd_send_toMotor_RL-=cmd_send_brake;
|
||||
cmd_send_toMotor_RR-=cmd_send_brake;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!controllers_connected || !armed) { //controllers not connected or not armed
|
||||
cmd_send=0;
|
||||
cmd_send_toMotor=0; //safety off
|
||||
cmd_send_toMotor_FL=0; //safety off
|
||||
cmd_send_toMotor_FR=0; //safety off
|
||||
cmd_send_toMotor_RL=0; //safety off
|
||||
cmd_send_toMotor_RR=0; //safety off
|
||||
}
|
||||
|
||||
escFront.setSpeed(cmd_send_toMotor,cmd_send_toMotor);
|
||||
escRear.setSpeed(cmd_send_toMotor,cmd_send_toMotor);
|
||||
escFront.setSpeed(cmd_send_toMotor_FL,cmd_send_toMotor_FR);
|
||||
escRear.setSpeed(cmd_send_toMotor_RL,cmd_send_toMotor_RR);
|
||||
|
||||
log_update=true;
|
||||
}
|
||||
|
@ -610,6 +739,7 @@ void readButtons() {
|
|||
static bool button_start_wait_release_flag=false;
|
||||
bool last_button_start_state=button_start_state;
|
||||
|
||||
|
||||
if (loopmillis > button_start_lastchange+DEBOUNCE_TIME) { //wait some time after last change
|
||||
if (digitalRead(PIN_PWRBUTTON) && !button_start_state) { //start engine button pressed and was not pressed before
|
||||
button_start_state=true; //pressed
|
||||
|
@ -641,23 +771,87 @@ void readButtons() {
|
|||
writeLogComment(loopmillis, "Disarmed by button");
|
||||
}
|
||||
if (button_start_longpress_flag) {
|
||||
#ifndef CALIBRATION_THROTTLE_CURVE //disable arming when throttle calibration enabled (because errorcheck is disabled)
|
||||
if (escFront.getControllerConnected() && escRear.getControllerConnected()) {
|
||||
armed=true; //arm if button pressed long enough
|
||||
writeLogComment(loopmillis, "Armed by button");
|
||||
if (control_buttonA) { //button A is held down during start button press
|
||||
rc_fullcontrol_enabled=false;
|
||||
rc_steer_enabled=false;
|
||||
if (control_buttonA && control_buttonB) { //button A and B is held down during start button press
|
||||
uint8_t rcmode=getRCMode(6);
|
||||
if (getRCThrottle()==0 && getRCBrake()==0) {
|
||||
switch (rcmode) {
|
||||
case 0:
|
||||
throttle_max=250;
|
||||
reverse_speed=0.15;
|
||||
max_acceleration_rate=SLOW_MAX_ACCELERATION_RATE;
|
||||
writeLogComment(loopmillis, "Mode: RC 0");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
throttle_max=250;
|
||||
reverse_speed=0.15;
|
||||
max_acceleration_rate=MEDIUM_MAX_ACCELERATION_RATE;
|
||||
writeLogComment(loopmillis, "Mode: RC 1");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
throttle_max=300;
|
||||
reverse_speed=0.2;
|
||||
max_acceleration_rate=NORMAL_MAX_ACCELERATION_RATE;
|
||||
writeLogComment(loopmillis, "Mode: RC 2");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
throttle_max=400;
|
||||
reverse_speed=0.25;
|
||||
max_acceleration_rate=NORMAL_MAX_ACCELERATION_RATE;
|
||||
writeLogComment(loopmillis, "Mode: RC 3");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
throttle_max=600;
|
||||
reverse_speed=0.25;
|
||||
max_acceleration_rate=NORMAL_MAX_ACCELERATION_RATE;
|
||||
writeLogComment(loopmillis, "Mode: RC 4");
|
||||
break;
|
||||
|
||||
case 5:
|
||||
throttle_max=750;
|
||||
reverse_speed=0.25;
|
||||
max_acceleration_rate=NORMAL_MAX_ACCELERATION_RATE;
|
||||
writeLogComment(loopmillis, "Mode: RC 5");
|
||||
break;
|
||||
}
|
||||
|
||||
rc_fullcontrol_enabled=true;
|
||||
rc_steer_enabled=true;
|
||||
}else{
|
||||
writeLogComment(loopmillis, "Not Arming. RC throttle and brake not zero");
|
||||
armed=false;
|
||||
}
|
||||
|
||||
}else if (control_buttonA) { //button A is held down during start button press
|
||||
throttle_max=1000;
|
||||
reverse_speed=0.25;
|
||||
max_acceleration_rate=NORMAL_MAX_ACCELERATION_RATE;
|
||||
writeLogComment(loopmillis, "Mode: Fast");
|
||||
}else if (control_buttonB) { //button B is held down during start button press
|
||||
throttle_max=750;
|
||||
reverse_speed=0.25;
|
||||
max_acceleration_rate=SLOW_MAX_ACCELERATION_RATE;
|
||||
writeLogComment(loopmillis, "Mode: Medium");
|
||||
}else { //no control button pressed during start
|
||||
throttle_max=250;
|
||||
reverse_speed=0.15;
|
||||
max_acceleration_rate=SLOW_MAX_ACCELERATION_RATE;
|
||||
writeLogComment(loopmillis, "Mode: Slow");
|
||||
}
|
||||
|
||||
}else{
|
||||
writeLogComment(loopmillis, "Unable to arm");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -682,10 +876,31 @@ void readADSButtons() {
|
|||
|
||||
if (control_buttonA && !last_control_buttonA) { //button A was just pressed
|
||||
writeLogComment(loopmillis, "Button A Pressed");
|
||||
|
||||
if (!armed) { //standing disarmed display is showing
|
||||
if (standingDisplayScreen<NUM_STANDINGDISPLAYSCREEN-1){
|
||||
standingDisplayScreen++;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CALIBRATION_THROTTLE_CURVE
|
||||
if (standingDisplayScreen==(NUM_STANDINGDISPLAYSCREEN-1)) { //on last page and button A pressed
|
||||
Serial.print(ads_throttle_A_raw); Serial.print(',');
|
||||
Serial.println(ads_throttle_B_raw);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (control_buttonB && !last_control_buttonB) { //button B was just pressed
|
||||
writeLogComment(loopmillis, "Button B Pressed");
|
||||
|
||||
if (!armed) { //standing disarmed display is showing
|
||||
if (standingDisplayScreen>0){
|
||||
standingDisplayScreen--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,52 +1,114 @@
|
|||
import matplotlib.pyplot as plt
|
||||
import csv
|
||||
#import csv
|
||||
import pandas as pd
|
||||
|
||||
x=[]
|
||||
speed_FrontL=[]
|
||||
speed_FrontR=[]
|
||||
speed_RearL=[]
|
||||
speed_RearR=[]
|
||||
|
||||
fp = open('LOG00203c_replacedFrontLeftWheel.TXT')
|
||||
|
||||
rdr = csv.DictReader(filter(lambda row: row[0]!='#', fp))
|
||||
for row in rdr:
|
||||
#print(row)
|
||||
x.append(float(row['cmd_FrontL']))
|
||||
|
||||
speed_FrontL.append(float(row['speed_FrontL']))
|
||||
speed_FrontR.append(float(row['speed_FrontR']))
|
||||
speed_RearL.append(float(row['speed_RearL']))
|
||||
speed_RearR.append(float(row['speed_RearR']))
|
||||
fp.close()
|
||||
import numpy as np
|
||||
|
||||
|
||||
#plt.plot(x,y, label='Loaded from file!')
|
||||
scattersize=5
|
||||
scatteralpha=0.1
|
||||
plt.scatter(x,speed_FrontL, s=scattersize, alpha=scatteralpha, label="speed_FrontL")
|
||||
plt.scatter(x,speed_FrontR, s=scattersize, alpha=scatteralpha, label="speed_FrontR")
|
||||
plt.scatter(x,speed_RearL, s=scattersize, alpha=scatteralpha, label="speed_RearL")
|
||||
plt.scatter(x,speed_RearR, s=scattersize, alpha=scatteralpha, label="speed_RearR")
|
||||
plt.xlabel('cmd')
|
||||
plt.ylabel('speed')
|
||||
plt.title('Interesting Graph\nCheck it out')
|
||||
plt.legend()
|
||||
plt.show()
|
||||
import argparse
|
||||
|
||||
def mapRange(value, inMin, inMax, outMin, outMax,constrain=False):
|
||||
if constrain:
|
||||
return max(outMin, min(outMax, outMin + (((value - inMin) / (inMax - inMin)) * (outMax - outMin))))
|
||||
else:
|
||||
return outMin + (((value - inMin) / (inMax - inMin)) * (outMax - outMin))
|
||||
|
||||
|
||||
'''
|
||||
with open(,'r') as csvfile:
|
||||
plots = csv.reader(filter(lambda row: row[0]!='#', csvfile), delimiter=',')
|
||||
for row in plots:
|
||||
x.append(float(row[0]))
|
||||
y.append(float(row[1]))
|
||||
parser = argparse.ArgumentParser(description='Analyzes fixed csv logs from bobbycar')
|
||||
parser.add_argument('-i', '--input', type=argparse.FileType('r'), required=True, help="input csv log file")
|
||||
args = parser.parse_args()
|
||||
|
||||
plt.plot(x,y, label='Loaded from file!')
|
||||
plt.xlabel('x')
|
||||
plt.ylabel('y')
|
||||
plt.title('Interesting Graph\nCheck it out')
|
||||
plt.legend()
|
||||
plt.show()
|
||||
'''
|
||||
df = pd.read_csv(args.input.name)
|
||||
|
||||
x = df['timestamp']
|
||||
x = [i-x[0] for i in x] #offset time by starttime
|
||||
|
||||
|
||||
|
||||
def template():
|
||||
scattersize=1
|
||||
scatteralpha=0.1
|
||||
|
||||
|
||||
fig, ax1 = plt.subplots()
|
||||
|
||||
ax2 = ax1.twinx()
|
||||
|
||||
|
||||
#plt.scatter(x,df['rpm_FrontL'], s=scattersize, alpha=scatteralpha, label="rpm_FrontL")
|
||||
ax1.plot(x,np.array(df['temp_Front']), c='#0000ff', alpha=0.5, label="temp_Front")
|
||||
ax1.plot(x,np.array(df['temp_Rear']), c='#ff0000', alpha=0.5, label="temp_Rear")
|
||||
ax1.plot(x,np.array(df['temp_Air']), c='#00ff00', alpha=0.5, label="temp_Air")
|
||||
#ax2.plot(x,np.array(df['throttle']), c='g', alpha=0.5, label="throttle")
|
||||
|
||||
|
||||
#confidence
|
||||
#confidence_FrontL=[abs(x-df['cmd_FrontL'][i-5 if i>4 else 0])+abs(x-df['cmd_FrontL'][i-10 if i>9 else 0])+abs(x-df['cmd_FrontL'][i-20 if i>19 else 0]) for i,x in enumerate(df['cmd_FrontL'])]
|
||||
#confidence_FrontL=[mapRange(x,0,50,1.0,0.0,True) for x in confidence_FrontL]
|
||||
|
||||
|
||||
#ax1.scatter(df['cmd_FrontL'],df['rpm_FrontL'], s=scattersize, alpha=scatteralpha, label="FrontL")
|
||||
#ax1.scatter(df['cmd_FrontR'],df['rpm_FrontR'], s=scattersize, alpha=scatteralpha, label="FrontR")
|
||||
#ax1.scatter(df['cmd_RearL'],df['rpm_RearL'], s=scattersize, alpha=scatteralpha, label="RearL")
|
||||
#ax1.scatter(df['cmd_RearR'],df['rpm_RearR'], s=scattersize, alpha=scatteralpha, label="RearR")
|
||||
|
||||
ax1.set_xlabel('timestamp')
|
||||
#plt.ylabel('data')
|
||||
ax1.set_ylabel('first axis')
|
||||
ax2.set_ylabel('second axis')
|
||||
#plt.title('')
|
||||
ax1.legend(loc='upper left')
|
||||
ax2.legend(loc='upper right')
|
||||
plt.show()
|
||||
|
||||
|
||||
def rpmDifference():
|
||||
scattersize=1
|
||||
scatteralpha=0.1
|
||||
|
||||
|
||||
fig, ax1 = plt.subplots()
|
||||
|
||||
#confidence_FrontL=[abs(x-df['cmd_FrontL'][i-5 if i>4 else 0])+abs(x-df['cmd_FrontL'][i-10 if i>9 else 0])+abs(x-df['cmd_FrontL'][i-20 if i>19 else 0]) for i,x in enumerate(df['cmd_FrontL'])]
|
||||
frontRPMdiff=np.convolve(np.array(df['rpm_FrontL'])-np.array(df['rpm_FrontR']), np.ones(10)/10, mode='same')
|
||||
rearRPMdiff=np.convolve(np.array(df['rpm_RearL'])-np.array(df['rpm_RearR']), np.ones(10)/10, mode='same')
|
||||
|
||||
ax1.plot(x,frontRPMdiff, c='#0000ff', alpha=0.5, label="rpm Difference Front")
|
||||
ax1.plot(x,rearRPMdiff, c='#00ff00', alpha=0.5, label="rpm Difference Rear")
|
||||
|
||||
ax1.set_xlabel('timestamp')
|
||||
ax1.set_ylabel('rpm Difference')
|
||||
ax1.legend(loc='upper left')
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_rpmVsCurrent():
|
||||
scattersize=2
|
||||
scatteralpha=0.5
|
||||
|
||||
#confidence
|
||||
#confidence_FrontL=[abs(x-df['cmd_FrontL'][i-5 if i>4 else 0])+abs(x-df['cmd_FrontL'][i-10 if i>9 else 0])+abs(x-df['cmd_FrontL'][i-20 if i>19 else 0]) for i,x in enumerate(df['cmd_FrontL'])]
|
||||
#confidence_FrontL=[mapRange(x,0,50,1.0,0.0,True) for x in confidence_FrontL]
|
||||
|
||||
|
||||
|
||||
fig, ax1 = plt.subplots()
|
||||
ax1.scatter(df['rpm_FrontL'],df['current_FrontL'], s=5, alpha=scatteralpha, label="FrontL")
|
||||
ax1.scatter(df['rpm_FrontR'],df['current_FrontR'], s=5, alpha=scatteralpha, label="FrontR")
|
||||
#ax1.scatter(df['cmd_FrontR'],df['rpm_FrontR'], s=scattersize, alpha=scatteralpha, label="FrontR")
|
||||
#ax1.scatter(df['cmd_RearL'],df['rpm_RearL'], s=scattersize, alpha=scatteralpha, label="RearL")
|
||||
#ax1.scatter(df['cmd_RearR'],df['rpm_RearR'], s=scattersize, alpha=scatteralpha, label="RearR")
|
||||
|
||||
ax1.set_xlabel('rpm')
|
||||
ax1.set_ylabel('current (A)')
|
||||
plt.title('rpm vs current')
|
||||
ax1.legend(loc='upper left')
|
||||
plt.show()
|
||||
|
||||
|
||||
#plot_rpmVsCurrent()
|
||||
rpmDifference()
|
||||
|
||||
|
||||
|
||||
exit()
|
||||
|
|
232
logdata_visualization/copyLogsFromBobbycar.py
Normal file
232
logdata_visualization/copyLogsFromBobbycar.py
Normal file
|
@ -0,0 +1,232 @@
|
|||
|
||||
import serial
|
||||
import os
|
||||
import time
|
||||
import random
|
||||
import string
|
||||
|
||||
import argparse
|
||||
chunksize=4096
|
||||
|
||||
#LOG0002
|
||||
#32 = 124 kbps
|
||||
#128 = 263 kbps
|
||||
#4096 = 416 kbps
|
||||
#32768 = 427 kbps
|
||||
#65536 = failed
|
||||
|
||||
serialport = serial.Serial(port='/dev/ttyACM0', baudrate=115200, timeout=1)
|
||||
|
||||
def establish_connection():
|
||||
|
||||
serialport.write("\n".encode())
|
||||
|
||||
|
||||
serialport.write("echo off\n".encode())
|
||||
time.sleep(0.1)
|
||||
while len(serialport.readline())>0:
|
||||
continue
|
||||
|
||||
|
||||
serialport.write("test\n".encode())
|
||||
time.sleep(0.1)
|
||||
response = serialport.readline()
|
||||
hrresponse=response.rstrip().decode('ascii')
|
||||
if hrresponse != "OK":
|
||||
print("Unexpected test response:"+str(response))
|
||||
exit()
|
||||
|
||||
def get_filenames():
|
||||
|
||||
filenames=[]
|
||||
|
||||
serialport.write("ls\n".encode())
|
||||
while True:
|
||||
response = serialport.readline()
|
||||
hrresponse=response.rstrip().decode('ascii')
|
||||
if(len(response))>0:
|
||||
#print(hrresponse)
|
||||
filenames.append(hrresponse)
|
||||
|
||||
else:
|
||||
break
|
||||
|
||||
return filenames
|
||||
|
||||
|
||||
def get_filesize(filename):
|
||||
|
||||
filesize=0
|
||||
|
||||
serialport.write(("sizeof "+str(filename)+"\n").encode())
|
||||
time.sleep(0.1)
|
||||
response = serialport.readline()
|
||||
hrresponse=response.rstrip().decode('ascii')
|
||||
if(len(response))>0:
|
||||
filesize=int(hrresponse)
|
||||
|
||||
return filesize
|
||||
|
||||
|
||||
def copy_file(source,destination,expectedsize):
|
||||
os.makedirs(os.path.dirname(writefilename), exist_ok=True)
|
||||
|
||||
|
||||
transferstarttime=time.time()
|
||||
chunkstarttime=time.time()
|
||||
last_print=time.time()
|
||||
|
||||
with open(writefilename, 'wb') as writer:
|
||||
serialport.write(("chunksize "+str(chunksize)+"\n").encode())
|
||||
serialport.write(("get "+filename+"\n").encode())
|
||||
time.sleep(0.1)
|
||||
|
||||
|
||||
acc_datalen=0
|
||||
|
||||
while True:
|
||||
|
||||
'''
|
||||
response = serialport.readline()
|
||||
hrresponse=response.rstrip().decode('ascii')
|
||||
if(len(response))>0:
|
||||
#print(hrresponse)
|
||||
writer.write(response)
|
||||
|
||||
else:
|
||||
break
|
||||
'''
|
||||
|
||||
|
||||
data=serialport.read(chunksize)
|
||||
|
||||
if(len(data))>0: #data received
|
||||
#print("received "+str(len(data))+" bytes")
|
||||
#hrresponse=data.rstrip().decode('ascii')
|
||||
#print(hrresponse)
|
||||
|
||||
acc_datalen+=len(data)
|
||||
|
||||
checksum=(sum(data) & 0xFF)
|
||||
checksumarray=bytearray([checksum])
|
||||
|
||||
writer.write(data)
|
||||
serialport.write(checksumarray) #request next chunk by sending checksum of last chunk
|
||||
|
||||
else:
|
||||
break
|
||||
|
||||
|
||||
if (time.time()-last_print>0.5):
|
||||
last_print=time.time()
|
||||
chunkduration=time.time()-chunkstarttime
|
||||
chunkstarttime=time.time()
|
||||
progress=0
|
||||
if expectedsize>0:
|
||||
progress=acc_datalen/expectedsize
|
||||
print(str(round(progress*100,0))+"% \t"+str(round(chunkduration*1000,3))+" ms for "+str(len(data))+" Byte \t = "+str(round((len(data)/chunkduration)/1000,3))+" kB/s")
|
||||
|
||||
|
||||
fileduration=time.time()-transferstarttime
|
||||
|
||||
file_stats=os.stat(writefilename)
|
||||
print("Finished transfer of "+str(acc_datalen)+" B or "+str(file_stats.st_size)+" (os) Byte in "+str(fileduration)+" s \t = "+str(round(file_stats.st_size/fileduration/1000,3))+" kB/s")
|
||||
|
||||
|
||||
return acc_datalen
|
||||
|
||||
|
||||
|
||||
|
||||
def log_off():
|
||||
serialport.write(("log off\n").encode())
|
||||
time.sleep(0.1)
|
||||
response = serialport.readline()
|
||||
hrresponse=response.rstrip().decode('ascii')
|
||||
if (not hrresponse.startswith("Log disabled")):
|
||||
print("Unexpected response:"+str(response))
|
||||
exit()
|
||||
|
||||
def delete_file(filename):
|
||||
|
||||
|
||||
serialport.write(("rm "+filename+"\n").encode())
|
||||
time.sleep(0.1)
|
||||
response = serialport.readline()
|
||||
hrresponse=response.rstrip().decode('ascii')
|
||||
if hrresponse != "OK":
|
||||
print("Unexpected response:"+str(response))
|
||||
exit()
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='Transfers log files from bobbycar over serial')
|
||||
parser.add_argument('-o', '--output', nargs='?', help="output directory")
|
||||
parser.add_argument('-d','--delete', action="store_true", help="delete files after transfer")
|
||||
args = parser.parse_args()
|
||||
outputfolder="sdcard"
|
||||
if (args.output is not None):
|
||||
outputfolder = args.output
|
||||
if(outputfolder[-1]=='/'):
|
||||
outputfolder=outputfolder[:-1] #remove last slash
|
||||
print("Outputfolder:"+outputfolder)
|
||||
|
||||
|
||||
if serialport.isOpen():
|
||||
|
||||
establish_connection()
|
||||
|
||||
|
||||
|
||||
#Get File List
|
||||
filenames=get_filenames()
|
||||
|
||||
|
||||
#Copy all Files
|
||||
|
||||
failed=0
|
||||
|
||||
for filename in filenames:
|
||||
print("Reading file "+filename)
|
||||
expectedsize=get_filesize(filename)
|
||||
print("Expecting "+str(expectedsize)+" Byte")
|
||||
|
||||
writefilename=outputfolder+'/'+filename
|
||||
receivedsize=copy_file(filename,writefilename,expectedsize)
|
||||
|
||||
if (expectedsize!=receivedsize):
|
||||
print("Warning: Filesize does not match!")
|
||||
failed+=1
|
||||
|
||||
print("")
|
||||
|
||||
print(str(len(filenames))+" Files copied with "+str(failed)+" failed")
|
||||
|
||||
|
||||
|
||||
#Delete all files
|
||||
if (args.delete):
|
||||
if (failed>0):
|
||||
print("Copy not successful. Files won't be deleted!")
|
||||
exit()
|
||||
deletecheckstring=''.join(random.choices(string.ascii_lowercase, k=3))
|
||||
deletecheck=input("Enter "+deletecheckstring+" to confirm deletion of "+str(len(filenames))+" files on bobbycar:")
|
||||
|
||||
if (deletecheck==deletecheckstring):
|
||||
log_off()
|
||||
for filename in filenames:
|
||||
print("Deleting "+filename)
|
||||
delete_file(filename)
|
||||
else:
|
||||
print("Verification failed!")
|
||||
|
||||
|
||||
|
||||
serialport.write("echo on\n".encode())
|
||||
time.sleep(0.1)
|
||||
|
||||
serialport.close()
|
||||
|
|
@ -2,12 +2,16 @@ import numpy as np
|
|||
from datetime import datetime
|
||||
import time
|
||||
import argparse
|
||||
import os.path
|
||||
|
||||
parser = argparse.ArgumentParser(description='Copys, renames and fixes logfiles written by bobbycar sd logger.')
|
||||
parser.add_argument('--input', type=argparse.FileType('r'), nargs='+')
|
||||
parser.add_argument('--output', nargs='?', type=argparse.FileType('w'))
|
||||
parser.add_argument('-i', '--input', type=argparse.FileType('r'), nargs='+', required=True, help="list of input log files")
|
||||
parser.add_argument('-o', '--output', nargs='?', type=argparse.FileType('w'), help="output filename")
|
||||
parser.add_argument('-c','--consecutive', action="store_true", help="add consecutive files to input. If the input file ends with a number the following logfiles will be added.")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
|
||||
ok=True
|
||||
|
||||
def getTimestamp(plines):
|
||||
|
@ -71,8 +75,46 @@ def filterLines(plines,plinesStarttime=None):
|
|||
return plines,pheader,pcommentlinesMask,pdatalines,pdatalinesFail,pdatalinesOK,pheaderSize,plinesOK,plinesStarttime
|
||||
|
||||
|
||||
inputFilenames=[]
|
||||
|
||||
if (args.consecutive):
|
||||
if(len(args.input)!=1):
|
||||
parser.error("in consequtive mode exactly one input file is required")
|
||||
exit()
|
||||
|
||||
nextFilename=args.input[0].name
|
||||
while os.path.isfile(nextFilename):
|
||||
print(nextFilename+" exists")
|
||||
inputFilenames.append(nextFilename)
|
||||
|
||||
digitStartpos=len(nextFilename)-1
|
||||
digitEndpos=len(nextFilename)
|
||||
|
||||
|
||||
|
||||
while (not nextFilename[digitStartpos:digitEndpos].isdigit() and digitStartpos>0 and digitEndpos>0):
|
||||
digitStartpos-=1
|
||||
digitEndpos-=1
|
||||
|
||||
while (nextFilename[digitStartpos:digitEndpos].isdigit() and digitStartpos>0 and digitEndpos>0):
|
||||
digitStartpos-=1
|
||||
|
||||
digitStartpos+=1
|
||||
|
||||
|
||||
number=int(nextFilename[digitStartpos:digitEndpos])+1
|
||||
nextFilename=nextFilename[0:digitStartpos]+str(number).zfill(digitEndpos-digitStartpos)+nextFilename[digitEndpos:]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
else:
|
||||
inputFilenames=[x.name for x in args.input]
|
||||
|
||||
|
||||
|
||||
|
||||
inputFilenames=[x.name for x in args.input]
|
||||
|
||||
outputFilename=None
|
||||
if args.output is not None:
|
||||
|
@ -106,7 +148,7 @@ for inputFilename in inputFilenames:
|
|||
|
||||
linesStarttime+=_linesStarttime
|
||||
|
||||
print("Line in file="+str(len(inputlines)))
|
||||
print("Lines in file="+str(len(inputlines)))
|
||||
|
||||
assert len(lines)==len(linesStarttime), "Length of lines and linesStarttime does not match"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue