blob: 289913f6f3dc941094cd37796447c2426b8cf9e8 [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(
Maxwell Hendersonb392b742023-03-05 07:53:51 -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(
Maxwell Hendersonb392b742023-03-05 07:53:51 -080044 " Trajectory(dynamics, &hybrid_roll_joint_loop->plant(), %s(), 0.005), "
milind-ua7af5162023-02-20 15:13:48 -080045 % (path_function_name(str(name))))
Maxwell Hendersonb392b742023-03-05 07:53:51 -080046 cc_file.append(f"\"{path_function_name(str(name))}\");")
milind-ua7af5162023-02-20 15:13:48 -080047
48 start_index = None
49 end_index = None
Austin Schuh9a11ebd2023-02-26 14:16:31 -080050 for key in sorted(graph_paths.points.keys()):
51 point = graph_paths.points[key]
milind-u18a901d2023-02-17 21:51:55 -080052 if (point[:2] == segment.start
53 ).all() and point[2] == segment.alpha_rolls[0][1]:
Austin Schuh9a11ebd2023-02-26 14:16:31 -080054 start_index = key
milind-u18a901d2023-02-17 21:51:55 -080055 if (point[:2] == segment.end
56 ).all() and point[2] == segment.alpha_rolls[-1][1]:
Austin Schuh9a11ebd2023-02-26 14:16:31 -080057 end_index = key
milind-ua7af5162023-02-20 15:13:48 -080058
59 if reverse:
60 start_index, end_index = end_index, start_index
61
62 cc_file.append(
63 " edges.push_back(SearchGraph::Edge{%s(), %s()," %
64 (index_function_name(start_index), index_function_name(end_index)))
65 cc_file.append(
66 " (trajectories->back().trajectory.path().length() + 0.2)});"
67 )
68
69 # TODO(austin): Allow different vmaxes for different paths.
70 cc_file.append(" trajectories->back().trajectory.OptimizeTrajectory(")
71 cc_file.append(" trajectories->back().alpha_unitizer,")
72 cc_file.append(" trajectories->back().vmax);")
73 cc_file.append("")
74
75
76def main(argv):
77 cc_file = []
milind-ua7af5162023-02-20 15:13:48 -080078 cc_file.append("#include <memory>")
79 cc_file.append("")
80 cc_file.append(
milind-ua7af5162023-02-20 15:13:48 -080081 "#include \"frc971/control_loops/double_jointed_arm/graph.h\"")
milind-u18a901d2023-02-17 21:51:55 -080082 cc_file.append(
83 "#include \"y2023/control_loops/superstructure/arm/generated_graph.h\""
84 )
85 cc_file.append(
86 "#include \"y2023/control_loops/superstructure/arm/trajectory.h\"")
87 cc_file.append(
88 "#include \"y2023/control_loops/superstructure/roll/integral_hybrid_roll_plant.h\""
89 )
Austin Schuh7b8adf92023-02-22 21:17:31 -080090 cc_file.append("")
milind-ua7af5162023-02-20 15:13:48 -080091
milind-ua7af5162023-02-20 15:13:48 -080092 cc_file.append("using frc971::control_loops::arm::SearchGraph;")
milind-u18a901d2023-02-17 21:51:55 -080093 cc_file.append(
94 "using y2023::control_loops::superstructure::arm::Trajectory;")
95 cc_file.append("using y2023::control_loops::superstructure::arm::Path;")
96 cc_file.append("using y2023::control_loops::superstructure::arm::NSpline;")
97 cc_file.append(
98 "using y2023::control_loops::superstructure::arm::CosSpline;")
milind-ua7af5162023-02-20 15:13:48 -080099
100 cc_file.append("")
101 cc_file.append("namespace y2023 {")
102 cc_file.append("namespace control_loops {")
103 cc_file.append("namespace superstructure {")
104 cc_file.append("namespace arm {")
105
106 h_file = []
107 h_file.append(
108 "#ifndef Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_GENERATED_GRAPH_H_")
109 h_file.append(
110 "#define Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_GENERATED_GRAPH_H_")
111 h_file.append("")
112 h_file.append("#include <memory>")
113 h_file.append("")
114 h_file.append(
milind-ua7af5162023-02-20 15:13:48 -0800115 "#include \"frc971/control_loops/double_jointed_arm/graph.h\"")
116 h_file.append(
117 "#include \"y2023/control_loops/superstructure/arm/arm_constants.h\"")
milind-u18a901d2023-02-17 21:51:55 -0800118 h_file.append(
119 "#include \"y2023/control_loops/superstructure/arm/trajectory.h\"")
Maxwell Hendersonb392b742023-03-05 07:53:51 -0800120 h_file.append(
121 "#include \"y2023/control_loops/superstructure/arm/arm_trajectories_generated.h\""
122 )
milind-u18a901d2023-02-17 21:51:55 -0800123
milind-ua7af5162023-02-20 15:13:48 -0800124 h_file.append("")
125 h_file.append("namespace y2023 {")
126 h_file.append("namespace control_loops {")
127 h_file.append("namespace superstructure {")
128 h_file.append("namespace arm {")
129
milind-ua7af5162023-02-20 15:13:48 -0800130 h_file.append("using frc971::control_loops::arm::SearchGraph;")
131 h_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800132 "using y2023::control_loops::superstructure::arm::Trajectory;")
133 h_file.append("using y2023::control_loops::superstructure::arm::Path;")
134 h_file.append(
milind-ua7af5162023-02-20 15:13:48 -0800135 "using y2023::control_loops::superstructure::arm::kArmConstants;")
136
Maxwell Hendersonb392b742023-03-05 07:53:51 -0800137 h_file.append(
138 "using y2023::control_loops::superstructure::arm::TrajectoryAndParamsFbs;"
139 )
140
milind-ua7af5162023-02-20 15:13:48 -0800141 h_file.append("")
142 h_file.append("struct TrajectoryAndParams {")
143 h_file.append(" TrajectoryAndParams(double new_vmax,")
144 h_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800145 " const ::Eigen::Matrix<double, 3, 3> &new_alpha_unitizer,"
milind-ua7af5162023-02-20 15:13:48 -0800146 )
Maxwell Hendersonb392b742023-03-05 07:53:51 -0800147 h_file.append(
148 " Trajectory &&new_trajectory, std::string_view new_name)"
149 )
milind-ua7af5162023-02-20 15:13:48 -0800150 h_file.append(" : vmax(new_vmax),")
151 h_file.append(" alpha_unitizer(new_alpha_unitizer),")
Maxwell Hendersonb392b742023-03-05 07:53:51 -0800152 h_file.append(" trajectory(::std::move(new_trajectory)),")
153 h_file.append(" name(new_name) {}")
154 h_file.append(
155 "TrajectoryAndParams(const frc971::control_loops::arm::Dynamics *dynamics, const StateFeedbackHybridPlant<3, 1, 1> *roll, const TrajectoryAndParamsFbs &trajectory_and_params_fbs)"
156 )
157 h_file.append(": vmax(trajectory_and_params_fbs.vmax()),")
158 h_file.append(
159 "alpha_unitizer((trajectory_and_params_fbs.alpha_unitizer()->data(),")
160 h_file.append(" trajectory_and_params_fbs.alpha_unitizer()->data() +")
161 h_file.append(
162 " trajectory_and_params_fbs.alpha_unitizer()->size())),")
163 h_file.append(
164 "trajectory(dynamics, roll, *trajectory_and_params_fbs.trajectory()),")
165 h_file.append("name(trajectory_and_params_fbs.name()->string_view()) {}")
milind-ua7af5162023-02-20 15:13:48 -0800166 h_file.append(" double vmax;")
milind-u18a901d2023-02-17 21:51:55 -0800167 h_file.append(" ::Eigen::Matrix<double, 3, 3> alpha_unitizer;")
milind-ua7af5162023-02-20 15:13:48 -0800168 h_file.append(" Trajectory trajectory;")
Maxwell Hendersonb392b742023-03-05 07:53:51 -0800169 h_file.append(" std::string_view name;")
milind-ua7af5162023-02-20 15:13:48 -0800170 h_file.append("};")
171 h_file.append("")
172
173 # Now dump out the vertices and associated constexpr vertex name functions.
Austin Schuh9a11ebd2023-02-26 14:16:31 -0800174 for index, key in enumerate(sorted(graph_paths.points.keys())):
175 point = graph_paths.points[key]
milind-ua7af5162023-02-20 15:13:48 -0800176 h_file.append("")
177 h_file.append("constexpr uint32_t %s() { return %d; }" %
Austin Schuh9a11ebd2023-02-26 14:16:31 -0800178 (index_function_name(key), index))
Austin Schuha1381922023-02-26 22:27:05 -0800179 h_file.append("::Eigen::Matrix<double, 3, 1> %sPoint();" % key)
180 cc_file.append("::Eigen::Matrix<double, 3, 1> %sPoint() {" % key)
181 cc_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800182 " return (::Eigen::Matrix<double, 3, 1>() << %f, %f, %f).finished();"
Austin Schuh9a11ebd2023-02-26 14:16:31 -0800183 % (point[0], point[1], point[2]))
Austin Schuha1381922023-02-26 22:27:05 -0800184 cc_file.append("}")
milind-ua7af5162023-02-20 15:13:48 -0800185
186 front_points = [
187 index_function_name(point[1]) + "()"
188 for point in graph_paths.front_points
189 ]
190 h_file.append("")
191 h_file.append("constexpr ::std::array<uint32_t, %d> FrontPoints() {" %
192 len(front_points))
193 h_file.append(" return ::std::array<uint32_t, %d>{{%s}};" %
194 (len(front_points), ", ".join(front_points)))
195 h_file.append("}")
196
197 back_points = [
198 index_function_name(point[1]) + "()"
199 for point in graph_paths.back_points
200 ]
201 h_file.append("")
202 h_file.append("constexpr ::std::array<uint32_t, %d> BackPoints() {" %
203 len(back_points))
204 h_file.append(" return ::std::array<uint32_t, %d>{{%s}};" %
205 (len(back_points), ", ".join(back_points)))
206 h_file.append("}")
207
208 # Add the Make*Path functions.
209 h_file.append("")
210 cc_file.append("")
211 for name, segment in list(enumerate(graph_paths.unnamed_segments)) + [
212 (x.name, x) for x in graph_paths.named_segments
213 ]:
214 h_file.append("::std::unique_ptr<Path> %s();" %
215 path_function_name(name))
216 cc_file.append("::std::unique_ptr<Path> %s() {" %
217 path_function_name(name))
Austin Schuh7b8adf92023-02-22 21:17:31 -0800218 cc_file.append(" return ::std::unique_ptr<Path>(new Path(CosSpline{")
219 cc_file.append(" NSpline<4, 2>((Eigen::Matrix<double, 2, 4>() <<")
milind-u18a901d2023-02-17 21:51:55 -0800220 points = [
221 segment.start, segment.control1, segment.control2, segment.end
222 ]
Austin Schuh7b8adf92023-02-22 21:17:31 -0800223 cc_file.append(" " +
224 " ".join(["%.12f," % (p[0]) for p in points]))
225 cc_file.append(" " +
226 ", ".join(["%.12f" % (p[1]) for p in points]))
milind-u18a901d2023-02-17 21:51:55 -0800227
Austin Schuh7b8adf92023-02-22 21:17:31 -0800228 cc_file.append(" ).finished()), {")
milind-u18a901d2023-02-17 21:51:55 -0800229 for alpha, roll in segment.alpha_rolls:
230 cc_file.append(
Austin Schuh7b8adf92023-02-22 21:17:31 -0800231 " CosSpline::AlphaTheta{.alpha = %.12f, .theta = %.12f},"
232 % (alpha, roll))
milind-u18a901d2023-02-17 21:51:55 -0800233 cc_file.append(" }}));")
milind-ua7af5162023-02-20 15:13:48 -0800234 cc_file.append("}")
Austin Schuh7b8adf92023-02-22 21:17:31 -0800235 cc_file.append("")
milind-ua7af5162023-02-20 15:13:48 -0800236
237 # Matrix of nodes
milind-u18a901d2023-02-17 21:51:55 -0800238 h_file.append("::std::vector<::Eigen::Matrix<double, 3, 1>> PointList();")
milind-ua7af5162023-02-20 15:13:48 -0800239
240 cc_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800241 "::std::vector<::Eigen::Matrix<double, 3, 1>> PointList() {")
242 cc_file.append(" ::std::vector<::Eigen::Matrix<double, 3, 1>> points;")
Austin Schuh9a11ebd2023-02-26 14:16:31 -0800243 for key in sorted(graph_paths.points.keys()):
244 point = graph_paths.points[key]
milind-ua7af5162023-02-20 15:13:48 -0800245 cc_file.append(
milind-u18a901d2023-02-17 21:51:55 -0800246 " points.push_back((::Eigen::Matrix<double, 3, 1>() << %.12s, %.12s, %.12s).finished());"
Austin Schuh9a11ebd2023-02-26 14:16:31 -0800247 % (point[0], point[1], point[2]))
milind-ua7af5162023-02-20 15:13:48 -0800248 cc_file.append(" return points;")
249 cc_file.append("}")
250
251 # Now create the MakeSearchGraph function.
252 h_file.append("")
253 h_file.append("// Builds a search graph.")
254 h_file.append("SearchGraph MakeSearchGraph("
255 "const frc971::control_loops::arm::Dynamics *dynamics, "
256 "::std::vector<TrajectoryAndParams> *trajectories,")
Austin Schuh7b8adf92023-02-22 21:17:31 -0800257 h_file.append(
258 " const ::Eigen::Matrix<double, 3, 3> &alpha_unitizer,"
259 )
260 h_file.append(" double vmax,")
milind-u18a901d2023-02-17 21:51:55 -0800261 h_file.append(
262 "const StateFeedbackLoop<3, 1, 1, double, StateFeedbackHybridPlant<3, 1, 1>, HybridKalman<3, 1, 1>> *hybrid_roll_joint_loop);"
263 )
Austin Schuh7b8adf92023-02-22 21:17:31 -0800264 cc_file.append("")
265 cc_file.append("SearchGraph MakeSearchGraph(")
266 cc_file.append(" const frc971::control_loops::arm::Dynamics *dynamics,")
267 cc_file.append(" std::vector<TrajectoryAndParams> *trajectories,")
milind-u18a901d2023-02-17 21:51:55 -0800268 cc_file.append(
Austin Schuh7b8adf92023-02-22 21:17:31 -0800269 " const ::Eigen::Matrix<double, 3, 3> &alpha_unitizer, double vmax,"
270 )
271 cc_file.append(
272 " const StateFeedbackLoop<3, 1, 1, double, StateFeedbackHybridPlant<3, 1, 1>,"
273 )
274 cc_file.append(
275 " HybridKalman<3, 1, 1>> *hybrid_roll_joint_loop) {"
milind-u18a901d2023-02-17 21:51:55 -0800276 )
milind-ua7af5162023-02-20 15:13:48 -0800277 cc_file.append(" ::std::vector<SearchGraph::Edge> edges;")
278
279 index = 0
280 segments_and_names = list(enumerate(graph_paths.unnamed_segments)) + [
281 (x.name, x) for x in graph_paths.named_segments
282 ]
283
284 for name, segment in segments_and_names:
285 add_edge(cc_file, name, segment, index, False)
286 index += 1
287 add_edge(cc_file, name, segment, index, True)
288 index += 1
289
290 cc_file.append(" return SearchGraph(%d, ::std::move(edges));" %
291 len(graph_paths.points))
292 cc_file.append("}")
293
294 h_file.append("")
295 h_file.append("} // namespace arm")
296 h_file.append("} // namespace superstructure")
297 h_file.append("} // namespace control_loops")
298 h_file.append("} // namespace y2023")
299 h_file.append("")
300 h_file.append(
301 "#endif // Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_GENERATED_GRAPH_H_")
302
303 cc_file.append("} // namespace arm")
304 cc_file.append("} // namespace superstructure")
305 cc_file.append("} // namespace control_loops")
306 cc_file.append("} // namespace y2023")
307
308 if len(argv) == 3:
309 with open(argv[1], "w") as hfd:
310 hfd.write("\n".join(h_file))
311
312 with open(argv[2], "w") as ccfd:
313 ccfd.write("\n".join(cc_file))
314 else:
315 print("\n".join(h_file))
316 print("\n".join(cc_file))
317
318
319if __name__ == '__main__':
320 main(sys.argv)