blob: 06f036eabb15c6075230959bb53abd92ba993f95 [file] [log] [blame]
milind-ua7af5162023-02-20 15:13:48 -08001from __future__ import print_function
2import sys
3import numpy
4import graph_paths
5
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:
23 alpha_unitizer = "(::Eigen::Matrix<double, 2, 2>() << %f, %f, %f, %f).finished()" % (
24 segment.alpha_unitizer[0, 0], segment.alpha_unitizer[0, 1],
25 segment.alpha_unitizer[1, 0], segment.alpha_unitizer[1, 1])
26 cc_file.append(" trajectories->emplace_back(%s," % (vmax))
27 cc_file.append(" %s," % (alpha_unitizer))
28 if reverse:
29 cc_file.append(
30 " Trajectory(dynamics, Path::Reversed(%s()), 0.005, kArmConstants));"
31 % (path_function_name(str(name))))
32 else:
33 cc_file.append(
34 " Trajectory(dynamics, %s(), 0.005, kArmConstants));"
35 % (path_function_name(str(name))))
36
37 start_index = None
38 end_index = None
39 for point, name in graph_paths.points:
40 if (point == segment.start).all():
41 start_index = name
42 if (point == segment.end).all():
43 end_index = name
44
45 if reverse:
46 start_index, end_index = end_index, start_index
47
48 cc_file.append(
49 " edges.push_back(SearchGraph::Edge{%s(), %s()," %
50 (index_function_name(start_index), index_function_name(end_index)))
51 cc_file.append(
52 " (trajectories->back().trajectory.path().length() + 0.2)});"
53 )
54
55 # TODO(austin): Allow different vmaxes for different paths.
56 cc_file.append(" trajectories->back().trajectory.OptimizeTrajectory(")
57 cc_file.append(" trajectories->back().alpha_unitizer,")
58 cc_file.append(" trajectories->back().vmax);")
59 cc_file.append("")
60
61
62def main(argv):
63 cc_file = []
64 cc_file.append(
65 "#include \"y2023/control_loops/superstructure/arm/generated_graph.h\""
66 )
67 cc_file.append("")
68 cc_file.append("#include <memory>")
69 cc_file.append("")
70 cc_file.append(
71 "#include \"frc971/control_loops/double_jointed_arm/trajectory.h\"")
72 cc_file.append(
73 "#include \"frc971/control_loops/double_jointed_arm/graph.h\"")
74
75 cc_file.append("using frc971::control_loops::arm::Trajectory;")
76 cc_file.append("using frc971::control_loops::arm::Path;")
77 cc_file.append("using frc971::control_loops::arm::SearchGraph;")
78
79 cc_file.append("")
80 cc_file.append("namespace y2023 {")
81 cc_file.append("namespace control_loops {")
82 cc_file.append("namespace superstructure {")
83 cc_file.append("namespace arm {")
84
85 h_file = []
86 h_file.append(
87 "#ifndef Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_GENERATED_GRAPH_H_")
88 h_file.append(
89 "#define Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_GENERATED_GRAPH_H_")
90 h_file.append("")
91 h_file.append("#include <memory>")
92 h_file.append("")
93 h_file.append(
94 "#include \"frc971/control_loops/double_jointed_arm/trajectory.h\"")
95 h_file.append(
96 "#include \"frc971/control_loops/double_jointed_arm/graph.h\"")
97 h_file.append(
98 "#include \"y2023/control_loops/superstructure/arm/arm_constants.h\"")
99 h_file.append("")
100 h_file.append("namespace y2023 {")
101 h_file.append("namespace control_loops {")
102 h_file.append("namespace superstructure {")
103 h_file.append("namespace arm {")
104
105 h_file.append("using frc971::control_loops::arm::Trajectory;")
106 h_file.append("using frc971::control_loops::arm::Path;")
107 h_file.append("using frc971::control_loops::arm::SearchGraph;")
108 h_file.append(
109 "using y2023::control_loops::superstructure::arm::kArmConstants;")
110
111 h_file.append("")
112 h_file.append("struct TrajectoryAndParams {")
113 h_file.append(" TrajectoryAndParams(double new_vmax,")
114 h_file.append(
115 " const ::Eigen::Matrix<double, 2, 2> &new_alpha_unitizer,"
116 )
117 h_file.append(" Trajectory &&new_trajectory)")
118 h_file.append(" : vmax(new_vmax),")
119 h_file.append(" alpha_unitizer(new_alpha_unitizer),")
120 h_file.append(" trajectory(::std::move(new_trajectory)) {}")
121 h_file.append(" double vmax;")
122 h_file.append(" ::Eigen::Matrix<double, 2, 2> alpha_unitizer;")
123 h_file.append(" Trajectory trajectory;")
124 h_file.append("};")
125 h_file.append("")
126
127 # Now dump out the vertices and associated constexpr vertex name functions.
128 for index, point in enumerate(graph_paths.points):
129 h_file.append("")
130 h_file.append("constexpr uint32_t %s() { return %d; }" %
131 (index_function_name(point[1]), index))
132 h_file.append("inline ::Eigen::Matrix<double, 2, 1> %sPoint() {" %
133 point[1])
134 h_file.append(
135 " return (::Eigen::Matrix<double, 2, 1>() << %f, %f).finished();"
136 % (numpy.pi / 2.0 - point[0][0], numpy.pi / 2.0 - point[0][1]))
137 h_file.append("}")
138
139 front_points = [
140 index_function_name(point[1]) + "()"
141 for point in graph_paths.front_points
142 ]
143 h_file.append("")
144 h_file.append("constexpr ::std::array<uint32_t, %d> FrontPoints() {" %
145 len(front_points))
146 h_file.append(" return ::std::array<uint32_t, %d>{{%s}};" %
147 (len(front_points), ", ".join(front_points)))
148 h_file.append("}")
149
150 back_points = [
151 index_function_name(point[1]) + "()"
152 for point in graph_paths.back_points
153 ]
154 h_file.append("")
155 h_file.append("constexpr ::std::array<uint32_t, %d> BackPoints() {" %
156 len(back_points))
157 h_file.append(" return ::std::array<uint32_t, %d>{{%s}};" %
158 (len(back_points), ", ".join(back_points)))
159 h_file.append("}")
160
161 # Add the Make*Path functions.
162 h_file.append("")
163 cc_file.append("")
164 for name, segment in list(enumerate(graph_paths.unnamed_segments)) + [
165 (x.name, x) for x in graph_paths.named_segments
166 ]:
167 h_file.append("::std::unique_ptr<Path> %s();" %
168 path_function_name(name))
169 cc_file.append("::std::unique_ptr<Path> %s() {" %
170 path_function_name(name))
171 cc_file.append(" return ::std::unique_ptr<Path>(new Path({")
172 for point in segment.ToThetaPoints():
173 cc_file.append(" {{%.12f, %.12f, %.12f," %
174 (numpy.pi / 2.0 - point[0],
175 numpy.pi / 2.0 - point[1], -point[2]))
176 cc_file.append(" %.12f, %.12f, %.12f}}," %
177 (-point[3], -point[4], -point[5]))
178 cc_file.append(" }));")
179 cc_file.append("}")
180
181 # Matrix of nodes
182 h_file.append("::std::vector<::Eigen::Matrix<double, 2, 1>> PointList();")
183
184 cc_file.append(
185 "::std::vector<::Eigen::Matrix<double, 2, 1>> PointList() {")
186 cc_file.append(" ::std::vector<::Eigen::Matrix<double, 2, 1>> points;")
187 for point in graph_paths.points:
188 cc_file.append(
189 " points.push_back((::Eigen::Matrix<double, 2, 1>() << %.12s, %.12s).finished());"
190 % (numpy.pi / 2.0 - point[0][0], numpy.pi / 2.0 - point[0][1]))
191 cc_file.append(" return points;")
192 cc_file.append("}")
193
194 # Now create the MakeSearchGraph function.
195 h_file.append("")
196 h_file.append("// Builds a search graph.")
197 h_file.append("SearchGraph MakeSearchGraph("
198 "const frc971::control_loops::arm::Dynamics *dynamics, "
199 "::std::vector<TrajectoryAndParams> *trajectories,")
200 h_file.append(" "
201 "const ::Eigen::Matrix<double, 2, 2> &alpha_unitizer,")
202 h_file.append(" double vmax);")
203 cc_file.append("SearchGraph MakeSearchGraph("
204 "const frc971::control_loops::arm::Dynamics *dynamics, "
205 "::std::vector<TrajectoryAndParams> * /*trajectories*/,")
206 cc_file.append(" "
207 "const ::Eigen::Matrix<double, 2, 2> & /*alpha_unitizer*/,")
208 cc_file.append(" "
209 "double /*vmax*/) {")
210 cc_file.append(" ::std::vector<SearchGraph::Edge> edges;")
211
212 index = 0
213 segments_and_names = list(enumerate(graph_paths.unnamed_segments)) + [
214 (x.name, x) for x in graph_paths.named_segments
215 ]
216
217 for name, segment in segments_and_names:
218 add_edge(cc_file, name, segment, index, False)
219 index += 1
220 add_edge(cc_file, name, segment, index, True)
221 index += 1
222
223 cc_file.append(" return SearchGraph(%d, ::std::move(edges));" %
224 len(graph_paths.points))
225 cc_file.append("}")
226
227 h_file.append("")
228 h_file.append("} // namespace arm")
229 h_file.append("} // namespace superstructure")
230 h_file.append("} // namespace control_loops")
231 h_file.append("} // namespace y2023")
232 h_file.append("")
233 h_file.append(
234 "#endif // Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_GENERATED_GRAPH_H_")
235
236 cc_file.append("} // namespace arm")
237 cc_file.append("} // namespace superstructure")
238 cc_file.append("} // namespace control_loops")
239 cc_file.append("} // namespace y2023")
240
241 if len(argv) == 3:
242 with open(argv[1], "w") as hfd:
243 hfd.write("\n".join(h_file))
244
245 with open(argv[2], "w") as ccfd:
246 ccfd.write("\n".join(cc_file))
247 else:
248 print("\n".join(h_file))
249 print("\n".join(cc_file))
250
251
252if __name__ == '__main__':
253 main(sys.argv)