blob: 69e2497b78a46d5046ae779fe48a0ed12ace2c05 [file] [log] [blame]
milind-ua7af5162023-02-20 15:13:48 -08001from __future__ import print_function
2import sys
milind-u18a901d2023-02-17 21:51:55 -08003import numpy as np
4import y2023.control_loops.python.graph_paths as graph_paths
milind-ua7af5162023-02-20 15:13:48 -08005
6
7def index_function_name(name):
8 return "%sIndex" % name
9
10
11def path_function_name(name):
12 return "Make%sPath" % name
13
14
15def add_edge(cc_file, name, segment, index, reverse):
16 cc_file.append(" // Adding edge %d" % index)
17 vmax = "vmax"
18 if segment.vmax:
19 vmax = "::std::min(vmax, %f)" % segment.vmax
20
21 alpha_unitizer = "alpha_unitizer"
22 if segment.alpha_unitizer is not None:
milind-u18a901d2023-02-17 21:51:55 -080023 alpha_unitizer = "(::Eigen::Matrix<double, 3, 3>() << %f, %f, %f, %f, %f, %f, %f, %f, %f).finished()" % (
24 segment.alpha_unitizer[0, 0],
25 segment.alpha_unitizer[0, 1],
26 segment.alpha_unitizer[0, 2],
27 segment.alpha_unitizer[1, 0],
28 segment.alpha_unitizer[1, 1],
29 segment.alpha_unitizer[1, 2],
30 segment.alpha_unitizer[2, 0],
31 segment.alpha_unitizer[2, 1],
32 segment.alpha_unitizer[2, 2],
33 )
milind-ua7af5162023-02-20 15:13:48 -080034 cc_file.append(" trajectories->emplace_back(%s," % (vmax))
35 cc_file.append(" %s," % (alpha_unitizer))
36 if reverse:
37 cc_file.append(
milind-u18a901d2023-02-17 21:51:55 -080038 " Trajectory(dynamics, &hybrid_roll_joint_loop->plant(), Path::Reversed(%s()), 0.005));"
milind-ua7af5162023-02-20 15:13:48 -080039 % (path_function_name(str(name))))
40 else:
41 cc_file.append(
milind-u18a901d2023-02-17 21:51:55 -080042 " Trajectory(dynamics, &hybrid_roll_joint_loop->plant(), %s(), 0.005));"
milind-ua7af5162023-02-20 15:13:48 -080043 % (path_function_name(str(name))))
44
45 start_index = None
46 end_index = None
47 for point, name in graph_paths.points:
milind-u18a901d2023-02-17 21:51:55 -080048 if (point[:2] == segment.start
49 ).all() and point[2] == segment.alpha_rolls[0][1]:
milind-ua7af5162023-02-20 15:13:48 -080050 start_index = name
milind-u18a901d2023-02-17 21:51:55 -080051 if (point[:2] == segment.end
52 ).all() and point[2] == segment.alpha_rolls[-1][1]:
milind-ua7af5162023-02-20 15:13:48 -080053 end_index = name
54
55 if reverse:
56 start_index, end_index = end_index, start_index
57
58 cc_file.append(
59 " edges.push_back(SearchGraph::Edge{%s(), %s()," %
60 (index_function_name(start_index), index_function_name(end_index)))
61 cc_file.append(
62 " (trajectories->back().trajectory.path().length() + 0.2)});"
63 )
64
65 # TODO(austin): Allow different vmaxes for different paths.
66 cc_file.append(" trajectories->back().trajectory.OptimizeTrajectory(")
67 cc_file.append(" trajectories->back().alpha_unitizer,")
68 cc_file.append(" trajectories->back().vmax);")
69 cc_file.append("")
70
71
72def main(argv):
73 cc_file = []
milind-ua7af5162023-02-20 15:13:48 -080074 cc_file.append("")
75 cc_file.append("#include <memory>")
76 cc_file.append("")
77 cc_file.append(
milind-ua7af5162023-02-20 15:13:48 -080078 "#include \"frc971/control_loops/double_jointed_arm/graph.h\"")
milind-u18a901d2023-02-17 21:51:55 -080079 cc_file.append(
80 "#include \"y2023/control_loops/superstructure/arm/generated_graph.h\""
81 )
82 cc_file.append(
83 "#include \"y2023/control_loops/superstructure/arm/trajectory.h\"")
84 cc_file.append(
85 "#include \"y2023/control_loops/superstructure/roll/integral_hybrid_roll_plant.h\""
86 )
milind-ua7af5162023-02-20 15:13:48 -080087
milind-ua7af5162023-02-20 15:13:48 -080088 cc_file.append("using frc971::control_loops::arm::SearchGraph;")
milind-u18a901d2023-02-17 21:51:55 -080089 cc_file.append(
90 "using y2023::control_loops::superstructure::arm::Trajectory;")
91 cc_file.append("using y2023::control_loops::superstructure::arm::Path;")
92 cc_file.append("using y2023::control_loops::superstructure::arm::NSpline;")
93 cc_file.append(
94 "using y2023::control_loops::superstructure::arm::CosSpline;")
milind-ua7af5162023-02-20 15:13:48 -080095
96 cc_file.append("")
97 cc_file.append("namespace y2023 {")
98 cc_file.append("namespace control_loops {")
99 cc_file.append("namespace superstructure {")
100 cc_file.append("namespace arm {")
101
102 h_file = []
103 h_file.append(
104 "#ifndef Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_GENERATED_GRAPH_H_")
105 h_file.append(
106 "#define Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_GENERATED_GRAPH_H_")
107 h_file.append("")
108 h_file.append("#include <memory>")
109 h_file.append("")
110 h_file.append(
milind-ua7af5162023-02-20 15:13:48 -0800111 "#include \"frc971/control_loops/double_jointed_arm/graph.h\"")
112 h_file.append(
113 "#include \"y2023/control_loops/superstructure/arm/arm_constants.h\"")
milind-u18a901d2023-02-17 21:51:55 -0800114 h_file.append(
115 "#include \"y2023/control_loops/superstructure/arm/trajectory.h\"")
116
milind-ua7af5162023-02-20 15:13:48 -0800117 h_file.append("")
118 h_file.append("namespace y2023 {")
119 h_file.append("namespace control_loops {")
120 h_file.append("namespace superstructure {")
121 h_file.append("namespace arm {")
122
milind-ua7af5162023-02-20 15:13:48 -0800123 h_file.append("using frc971::control_loops::arm::SearchGraph;")
124 h_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800125 "using y2023::control_loops::superstructure::arm::Trajectory;")
126 h_file.append("using y2023::control_loops::superstructure::arm::Path;")
127 h_file.append(
milind-ua7af5162023-02-20 15:13:48 -0800128 "using y2023::control_loops::superstructure::arm::kArmConstants;")
129
130 h_file.append("")
131 h_file.append("struct TrajectoryAndParams {")
132 h_file.append(" TrajectoryAndParams(double new_vmax,")
133 h_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800134 " const ::Eigen::Matrix<double, 3, 3> &new_alpha_unitizer,"
milind-ua7af5162023-02-20 15:13:48 -0800135 )
136 h_file.append(" Trajectory &&new_trajectory)")
137 h_file.append(" : vmax(new_vmax),")
138 h_file.append(" alpha_unitizer(new_alpha_unitizer),")
139 h_file.append(" trajectory(::std::move(new_trajectory)) {}")
140 h_file.append(" double vmax;")
milind-u18a901d2023-02-17 21:51:55 -0800141 h_file.append(" ::Eigen::Matrix<double, 3, 3> alpha_unitizer;")
milind-ua7af5162023-02-20 15:13:48 -0800142 h_file.append(" Trajectory trajectory;")
143 h_file.append("};")
144 h_file.append("")
145
146 # Now dump out the vertices and associated constexpr vertex name functions.
147 for index, point in enumerate(graph_paths.points):
148 h_file.append("")
149 h_file.append("constexpr uint32_t %s() { return %d; }" %
150 (index_function_name(point[1]), index))
milind-u18a901d2023-02-17 21:51:55 -0800151 h_file.append("inline ::Eigen::Matrix<double, 3, 1> %sPoint() {" %
milind-ua7af5162023-02-20 15:13:48 -0800152 point[1])
153 h_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800154 " return (::Eigen::Matrix<double, 3, 1>() << %f, %f, %f).finished();"
milind-u060e4cf2023-02-22 00:08:52 -0800155 % (point[0][0], point[0][1], point[0][2]))
milind-ua7af5162023-02-20 15:13:48 -0800156 h_file.append("}")
157
158 front_points = [
159 index_function_name(point[1]) + "()"
160 for point in graph_paths.front_points
161 ]
162 h_file.append("")
163 h_file.append("constexpr ::std::array<uint32_t, %d> FrontPoints() {" %
164 len(front_points))
165 h_file.append(" return ::std::array<uint32_t, %d>{{%s}};" %
166 (len(front_points), ", ".join(front_points)))
167 h_file.append("}")
168
169 back_points = [
170 index_function_name(point[1]) + "()"
171 for point in graph_paths.back_points
172 ]
173 h_file.append("")
174 h_file.append("constexpr ::std::array<uint32_t, %d> BackPoints() {" %
175 len(back_points))
176 h_file.append(" return ::std::array<uint32_t, %d>{{%s}};" %
177 (len(back_points), ", ".join(back_points)))
178 h_file.append("}")
179
180 # Add the Make*Path functions.
181 h_file.append("")
182 cc_file.append("")
183 for name, segment in list(enumerate(graph_paths.unnamed_segments)) + [
184 (x.name, x) for x in graph_paths.named_segments
185 ]:
186 h_file.append("::std::unique_ptr<Path> %s();" %
187 path_function_name(name))
188 cc_file.append("::std::unique_ptr<Path> %s() {" %
189 path_function_name(name))
milind-u18a901d2023-02-17 21:51:55 -0800190 cc_file.append(
191 " return ::std::unique_ptr<Path>(new Path(CosSpline{NSpline<4, 2>((Eigen::Matrix<double, 2, 4>() << "
192 )
193 points = [
194 segment.start, segment.control1, segment.control2, segment.end
195 ]
196 for i in range(len(points)):
milind-u060e4cf2023-02-22 00:08:52 -0800197 cc_file.append("%.12f," % (points[i][0]))
milind-u18a901d2023-02-17 21:51:55 -0800198 for i in range(len(points)):
milind-u060e4cf2023-02-22 00:08:52 -0800199 cc_file.append(
200 "%.12f%s" %
201 (points[i][1], ", " if i != len(points) - 1 else ""))
milind-u18a901d2023-02-17 21:51:55 -0800202
203 cc_file.append(").finished()), {")
204 for alpha, roll in segment.alpha_rolls:
205 cc_file.append(
206 "CosSpline::AlphaTheta{.alpha = %.12f, .theta = %.12f}" %
milind-u060e4cf2023-02-22 00:08:52 -0800207 (alpha, roll))
milind-u18a901d2023-02-17 21:51:55 -0800208 if alpha != segment.alpha_rolls[-1][0]:
209 cc_file.append(", ")
210 cc_file.append(" }}));")
milind-ua7af5162023-02-20 15:13:48 -0800211 cc_file.append("}")
212
213 # Matrix of nodes
milind-u18a901d2023-02-17 21:51:55 -0800214 h_file.append("::std::vector<::Eigen::Matrix<double, 3, 1>> PointList();")
milind-ua7af5162023-02-20 15:13:48 -0800215
216 cc_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800217 "::std::vector<::Eigen::Matrix<double, 3, 1>> PointList() {")
218 cc_file.append(" ::std::vector<::Eigen::Matrix<double, 3, 1>> points;")
milind-ua7af5162023-02-20 15:13:48 -0800219 for point in graph_paths.points:
220 cc_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800221 " points.push_back((::Eigen::Matrix<double, 3, 1>() << %.12s, %.12s, %.12s).finished());"
milind-u060e4cf2023-02-22 00:08:52 -0800222 % (point[0][0], point[0][1], point[0][2]))
milind-ua7af5162023-02-20 15:13:48 -0800223 cc_file.append(" return points;")
224 cc_file.append("}")
225
226 # Now create the MakeSearchGraph function.
227 h_file.append("")
228 h_file.append("// Builds a search graph.")
229 h_file.append("SearchGraph MakeSearchGraph("
230 "const frc971::control_loops::arm::Dynamics *dynamics, "
231 "::std::vector<TrajectoryAndParams> *trajectories,")
232 h_file.append(" "
milind-u18a901d2023-02-17 21:51:55 -0800233 "const ::Eigen::Matrix<double, 3, 3> &alpha_unitizer,")
234 h_file.append(" "
235 "double vmax,")
236 h_file.append(
237 "const StateFeedbackLoop<3, 1, 1, double, StateFeedbackHybridPlant<3, 1, 1>, HybridKalman<3, 1, 1>> *hybrid_roll_joint_loop);"
238 )
milind-ua7af5162023-02-20 15:13:48 -0800239 cc_file.append("SearchGraph MakeSearchGraph("
240 "const frc971::control_loops::arm::Dynamics *dynamics, "
milind-u37385182023-02-20 15:07:28 -0800241 "::std::vector<TrajectoryAndParams> *trajectories,")
milind-ua7af5162023-02-20 15:13:48 -0800242 cc_file.append(" "
milind-u18a901d2023-02-17 21:51:55 -0800243 "const ::Eigen::Matrix<double, 3, 3> &alpha_unitizer,")
milind-ua7af5162023-02-20 15:13:48 -0800244 cc_file.append(" "
milind-u18a901d2023-02-17 21:51:55 -0800245 "double vmax,")
246 cc_file.append(
247 "const StateFeedbackLoop<3, 1, 1, double, StateFeedbackHybridPlant<3, 1, 1>, HybridKalman<3, 1, 1>> *hybrid_roll_joint_loop) {"
248 )
milind-ua7af5162023-02-20 15:13:48 -0800249 cc_file.append(" ::std::vector<SearchGraph::Edge> edges;")
250
251 index = 0
252 segments_and_names = list(enumerate(graph_paths.unnamed_segments)) + [
253 (x.name, x) for x in graph_paths.named_segments
254 ]
255
256 for name, segment in segments_and_names:
257 add_edge(cc_file, name, segment, index, False)
258 index += 1
259 add_edge(cc_file, name, segment, index, True)
260 index += 1
261
262 cc_file.append(" return SearchGraph(%d, ::std::move(edges));" %
263 len(graph_paths.points))
264 cc_file.append("}")
265
266 h_file.append("")
267 h_file.append("} // namespace arm")
268 h_file.append("} // namespace superstructure")
269 h_file.append("} // namespace control_loops")
270 h_file.append("} // namespace y2023")
271 h_file.append("")
272 h_file.append(
273 "#endif // Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_GENERATED_GRAPH_H_")
274
275 cc_file.append("} // namespace arm")
276 cc_file.append("} // namespace superstructure")
277 cc_file.append("} // namespace control_loops")
278 cc_file.append("} // namespace y2023")
279
280 if len(argv) == 3:
281 with open(argv[1], "w") as hfd:
282 hfd.write("\n".join(h_file))
283
284 with open(argv[2], "w") as ccfd:
285 ccfd.write("\n".join(cc_file))
286 else:
287 print("\n".join(h_file))
288 print("\n".join(cc_file))
289
290
291if __name__ == '__main__':
292 main(sys.argv)