blob: 054a32d9a32d045b1e5e045eff858b31b81f4f92 [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):
milind-u4037bc72023-02-22 21:39:40 -080016 segment.VerifyPoints()
17
milind-ua7af5162023-02-20 15:13:48 -080018 cc_file.append(" // Adding edge %d" % index)
19 vmax = "vmax"
20 if segment.vmax:
21 vmax = "::std::min(vmax, %f)" % segment.vmax
22
23 alpha_unitizer = "alpha_unitizer"
24 if segment.alpha_unitizer is not None:
milind-u18a901d2023-02-17 21:51:55 -080025 alpha_unitizer = "(::Eigen::Matrix<double, 3, 3>() << %f, %f, %f, %f, %f, %f, %f, %f, %f).finished()" % (
26 segment.alpha_unitizer[0, 0],
27 segment.alpha_unitizer[0, 1],
28 segment.alpha_unitizer[0, 2],
29 segment.alpha_unitizer[1, 0],
30 segment.alpha_unitizer[1, 1],
31 segment.alpha_unitizer[1, 2],
32 segment.alpha_unitizer[2, 0],
33 segment.alpha_unitizer[2, 1],
34 segment.alpha_unitizer[2, 2],
35 )
milind-ua7af5162023-02-20 15:13:48 -080036 cc_file.append(" trajectories->emplace_back(%s," % (vmax))
37 cc_file.append(" %s," % (alpha_unitizer))
38 if reverse:
39 cc_file.append(
milind-u18a901d2023-02-17 21:51:55 -080040 " Trajectory(dynamics, &hybrid_roll_joint_loop->plant(), Path::Reversed(%s()), 0.005));"
milind-ua7af5162023-02-20 15:13:48 -080041 % (path_function_name(str(name))))
42 else:
43 cc_file.append(
milind-u18a901d2023-02-17 21:51:55 -080044 " Trajectory(dynamics, &hybrid_roll_joint_loop->plant(), %s(), 0.005));"
milind-ua7af5162023-02-20 15:13:48 -080045 % (path_function_name(str(name))))
46
47 start_index = None
48 end_index = None
49 for point, name in graph_paths.points:
milind-u18a901d2023-02-17 21:51:55 -080050 if (point[:2] == segment.start
51 ).all() and point[2] == segment.alpha_rolls[0][1]:
milind-ua7af5162023-02-20 15:13:48 -080052 start_index = name
milind-u18a901d2023-02-17 21:51:55 -080053 if (point[:2] == segment.end
54 ).all() and point[2] == segment.alpha_rolls[-1][1]:
milind-ua7af5162023-02-20 15:13:48 -080055 end_index = name
56
57 if reverse:
58 start_index, end_index = end_index, start_index
59
60 cc_file.append(
61 " edges.push_back(SearchGraph::Edge{%s(), %s()," %
62 (index_function_name(start_index), index_function_name(end_index)))
63 cc_file.append(
64 " (trajectories->back().trajectory.path().length() + 0.2)});"
65 )
66
67 # TODO(austin): Allow different vmaxes for different paths.
68 cc_file.append(" trajectories->back().trajectory.OptimizeTrajectory(")
69 cc_file.append(" trajectories->back().alpha_unitizer,")
70 cc_file.append(" trajectories->back().vmax);")
71 cc_file.append("")
72
73
74def main(argv):
75 cc_file = []
milind-ua7af5162023-02-20 15:13:48 -080076 cc_file.append("#include <memory>")
77 cc_file.append("")
78 cc_file.append(
milind-ua7af5162023-02-20 15:13:48 -080079 "#include \"frc971/control_loops/double_jointed_arm/graph.h\"")
milind-u18a901d2023-02-17 21:51:55 -080080 cc_file.append(
81 "#include \"y2023/control_loops/superstructure/arm/generated_graph.h\""
82 )
83 cc_file.append(
84 "#include \"y2023/control_loops/superstructure/arm/trajectory.h\"")
85 cc_file.append(
86 "#include \"y2023/control_loops/superstructure/roll/integral_hybrid_roll_plant.h\""
87 )
Austin Schuh7b8adf92023-02-22 21:17:31 -080088 cc_file.append("")
milind-ua7af5162023-02-20 15:13:48 -080089
milind-ua7af5162023-02-20 15:13:48 -080090 cc_file.append("using frc971::control_loops::arm::SearchGraph;")
milind-u18a901d2023-02-17 21:51:55 -080091 cc_file.append(
92 "using y2023::control_loops::superstructure::arm::Trajectory;")
93 cc_file.append("using y2023::control_loops::superstructure::arm::Path;")
94 cc_file.append("using y2023::control_loops::superstructure::arm::NSpline;")
95 cc_file.append(
96 "using y2023::control_loops::superstructure::arm::CosSpline;")
milind-ua7af5162023-02-20 15:13:48 -080097
98 cc_file.append("")
99 cc_file.append("namespace y2023 {")
100 cc_file.append("namespace control_loops {")
101 cc_file.append("namespace superstructure {")
102 cc_file.append("namespace arm {")
103
104 h_file = []
105 h_file.append(
106 "#ifndef Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_GENERATED_GRAPH_H_")
107 h_file.append(
108 "#define Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_GENERATED_GRAPH_H_")
109 h_file.append("")
110 h_file.append("#include <memory>")
111 h_file.append("")
112 h_file.append(
milind-ua7af5162023-02-20 15:13:48 -0800113 "#include \"frc971/control_loops/double_jointed_arm/graph.h\"")
114 h_file.append(
115 "#include \"y2023/control_loops/superstructure/arm/arm_constants.h\"")
milind-u18a901d2023-02-17 21:51:55 -0800116 h_file.append(
117 "#include \"y2023/control_loops/superstructure/arm/trajectory.h\"")
118
milind-ua7af5162023-02-20 15:13:48 -0800119 h_file.append("")
120 h_file.append("namespace y2023 {")
121 h_file.append("namespace control_loops {")
122 h_file.append("namespace superstructure {")
123 h_file.append("namespace arm {")
124
milind-ua7af5162023-02-20 15:13:48 -0800125 h_file.append("using frc971::control_loops::arm::SearchGraph;")
126 h_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800127 "using y2023::control_loops::superstructure::arm::Trajectory;")
128 h_file.append("using y2023::control_loops::superstructure::arm::Path;")
129 h_file.append(
milind-ua7af5162023-02-20 15:13:48 -0800130 "using y2023::control_loops::superstructure::arm::kArmConstants;")
131
132 h_file.append("")
133 h_file.append("struct TrajectoryAndParams {")
134 h_file.append(" TrajectoryAndParams(double new_vmax,")
135 h_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800136 " const ::Eigen::Matrix<double, 3, 3> &new_alpha_unitizer,"
milind-ua7af5162023-02-20 15:13:48 -0800137 )
138 h_file.append(" Trajectory &&new_trajectory)")
139 h_file.append(" : vmax(new_vmax),")
140 h_file.append(" alpha_unitizer(new_alpha_unitizer),")
141 h_file.append(" trajectory(::std::move(new_trajectory)) {}")
142 h_file.append(" double vmax;")
milind-u18a901d2023-02-17 21:51:55 -0800143 h_file.append(" ::Eigen::Matrix<double, 3, 3> alpha_unitizer;")
milind-ua7af5162023-02-20 15:13:48 -0800144 h_file.append(" Trajectory trajectory;")
145 h_file.append("};")
146 h_file.append("")
147
148 # Now dump out the vertices and associated constexpr vertex name functions.
149 for index, point in enumerate(graph_paths.points):
150 h_file.append("")
151 h_file.append("constexpr uint32_t %s() { return %d; }" %
152 (index_function_name(point[1]), index))
milind-u18a901d2023-02-17 21:51:55 -0800153 h_file.append("inline ::Eigen::Matrix<double, 3, 1> %sPoint() {" %
milind-ua7af5162023-02-20 15:13:48 -0800154 point[1])
155 h_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800156 " return (::Eigen::Matrix<double, 3, 1>() << %f, %f, %f).finished();"
milind-u060e4cf2023-02-22 00:08:52 -0800157 % (point[0][0], point[0][1], point[0][2]))
milind-ua7af5162023-02-20 15:13:48 -0800158 h_file.append("}")
159
160 front_points = [
161 index_function_name(point[1]) + "()"
162 for point in graph_paths.front_points
163 ]
164 h_file.append("")
165 h_file.append("constexpr ::std::array<uint32_t, %d> FrontPoints() {" %
166 len(front_points))
167 h_file.append(" return ::std::array<uint32_t, %d>{{%s}};" %
168 (len(front_points), ", ".join(front_points)))
169 h_file.append("}")
170
171 back_points = [
172 index_function_name(point[1]) + "()"
173 for point in graph_paths.back_points
174 ]
175 h_file.append("")
176 h_file.append("constexpr ::std::array<uint32_t, %d> BackPoints() {" %
177 len(back_points))
178 h_file.append(" return ::std::array<uint32_t, %d>{{%s}};" %
179 (len(back_points), ", ".join(back_points)))
180 h_file.append("}")
181
182 # Add the Make*Path functions.
183 h_file.append("")
184 cc_file.append("")
185 for name, segment in list(enumerate(graph_paths.unnamed_segments)) + [
186 (x.name, x) for x in graph_paths.named_segments
187 ]:
188 h_file.append("::std::unique_ptr<Path> %s();" %
189 path_function_name(name))
190 cc_file.append("::std::unique_ptr<Path> %s() {" %
191 path_function_name(name))
Austin Schuh7b8adf92023-02-22 21:17:31 -0800192 cc_file.append(" return ::std::unique_ptr<Path>(new Path(CosSpline{")
193 cc_file.append(" NSpline<4, 2>((Eigen::Matrix<double, 2, 4>() <<")
milind-u18a901d2023-02-17 21:51:55 -0800194 points = [
195 segment.start, segment.control1, segment.control2, segment.end
196 ]
Austin Schuh7b8adf92023-02-22 21:17:31 -0800197 cc_file.append(" " +
198 " ".join(["%.12f," % (p[0]) for p in points]))
199 cc_file.append(" " +
200 ", ".join(["%.12f" % (p[1]) for p in points]))
milind-u18a901d2023-02-17 21:51:55 -0800201
Austin Schuh7b8adf92023-02-22 21:17:31 -0800202 cc_file.append(" ).finished()), {")
milind-u18a901d2023-02-17 21:51:55 -0800203 for alpha, roll in segment.alpha_rolls:
204 cc_file.append(
Austin Schuh7b8adf92023-02-22 21:17:31 -0800205 " CosSpline::AlphaTheta{.alpha = %.12f, .theta = %.12f},"
206 % (alpha, roll))
milind-u18a901d2023-02-17 21:51:55 -0800207 cc_file.append(" }}));")
milind-ua7af5162023-02-20 15:13:48 -0800208 cc_file.append("}")
Austin Schuh7b8adf92023-02-22 21:17:31 -0800209 cc_file.append("")
milind-ua7af5162023-02-20 15:13:48 -0800210
211 # Matrix of nodes
milind-u18a901d2023-02-17 21:51:55 -0800212 h_file.append("::std::vector<::Eigen::Matrix<double, 3, 1>> PointList();")
milind-ua7af5162023-02-20 15:13:48 -0800213
214 cc_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800215 "::std::vector<::Eigen::Matrix<double, 3, 1>> PointList() {")
216 cc_file.append(" ::std::vector<::Eigen::Matrix<double, 3, 1>> points;")
milind-ua7af5162023-02-20 15:13:48 -0800217 for point in graph_paths.points:
218 cc_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800219 " points.push_back((::Eigen::Matrix<double, 3, 1>() << %.12s, %.12s, %.12s).finished());"
milind-u060e4cf2023-02-22 00:08:52 -0800220 % (point[0][0], point[0][1], point[0][2]))
milind-ua7af5162023-02-20 15:13:48 -0800221 cc_file.append(" return points;")
222 cc_file.append("}")
223
224 # Now create the MakeSearchGraph function.
225 h_file.append("")
226 h_file.append("// Builds a search graph.")
227 h_file.append("SearchGraph MakeSearchGraph("
228 "const frc971::control_loops::arm::Dynamics *dynamics, "
229 "::std::vector<TrajectoryAndParams> *trajectories,")
Austin Schuh7b8adf92023-02-22 21:17:31 -0800230 h_file.append(
231 " const ::Eigen::Matrix<double, 3, 3> &alpha_unitizer,"
232 )
233 h_file.append(" double vmax,")
milind-u18a901d2023-02-17 21:51:55 -0800234 h_file.append(
235 "const StateFeedbackLoop<3, 1, 1, double, StateFeedbackHybridPlant<3, 1, 1>, HybridKalman<3, 1, 1>> *hybrid_roll_joint_loop);"
236 )
Austin Schuh7b8adf92023-02-22 21:17:31 -0800237 cc_file.append("")
238 cc_file.append("SearchGraph MakeSearchGraph(")
239 cc_file.append(" const frc971::control_loops::arm::Dynamics *dynamics,")
240 cc_file.append(" std::vector<TrajectoryAndParams> *trajectories,")
milind-u18a901d2023-02-17 21:51:55 -0800241 cc_file.append(
Austin Schuh7b8adf92023-02-22 21:17:31 -0800242 " const ::Eigen::Matrix<double, 3, 3> &alpha_unitizer, double vmax,"
243 )
244 cc_file.append(
245 " const StateFeedbackLoop<3, 1, 1, double, StateFeedbackHybridPlant<3, 1, 1>,"
246 )
247 cc_file.append(
248 " HybridKalman<3, 1, 1>> *hybrid_roll_joint_loop) {"
milind-u18a901d2023-02-17 21:51:55 -0800249 )
milind-ua7af5162023-02-20 15:13:48 -0800250 cc_file.append(" ::std::vector<SearchGraph::Edge> edges;")
251
252 index = 0
253 segments_and_names = list(enumerate(graph_paths.unnamed_segments)) + [
254 (x.name, x) for x in graph_paths.named_segments
255 ]
256
257 for name, segment in segments_and_names:
258 add_edge(cc_file, name, segment, index, False)
259 index += 1
260 add_edge(cc_file, name, segment, index, True)
261 index += 1
262
263 cc_file.append(" return SearchGraph(%d, ::std::move(edges));" %
264 len(graph_paths.points))
265 cc_file.append("}")
266
267 h_file.append("")
268 h_file.append("} // namespace arm")
269 h_file.append("} // namespace superstructure")
270 h_file.append("} // namespace control_loops")
271 h_file.append("} // namespace y2023")
272 h_file.append("")
273 h_file.append(
274 "#endif // Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_GENERATED_GRAPH_H_")
275
276 cc_file.append("} // namespace arm")
277 cc_file.append("} // namespace superstructure")
278 cc_file.append("} // namespace control_loops")
279 cc_file.append("} // namespace y2023")
280
281 if len(argv) == 3:
282 with open(argv[1], "w") as hfd:
283 hfd.write("\n".join(h_file))
284
285 with open(argv[2], "w") as ccfd:
286 ccfd.write("\n".join(cc_file))
287 else:
288 print("\n".join(h_file))
289 print("\n".join(cc_file))
290
291
292if __name__ == '__main__':
293 main(sys.argv)