Zakładam, że masz fizycznie poprawny ruch dla swojego statku, ponieważ w przeciwnym razie ta analiza nie zostanie przeprowadzona. Potrzebujesz czegoś silniejszego niż wydajność, aby poprawnie rozwiązać ten problem.
Każdy pędnik wytworzy dwa efekty na ruch statku: liniowy i kątowy. Można je rozpatrywać niezależnie. Jeśli pędnik wytwarza siłę f
w kierunku dir
i jest przesunięty względem środka masy o wektor r
(nie środek geometryczny ani środek duszka!), Wówczas wpływ na składową liniową jest:
t = f * dir // f is a scalar, dir is unit length
Moment obrotowy wpływa na prędkość kątową:
tau = f * <dir.x, dir.y, 0> CROSS <r.x, r.y, 0> // cross product
t
jest wektorem siły (tj. ciągiem liniowym). tau
jest znakiem skalarnym, który podzielony przez moment bezwładności masy da przyspieszenie kątowe. Istotne jest to, że dir
i r
to zarówno w tej samej przestrzeni współrzędnych, czyli zarówno w lokalnym układzie współrzędnych lub zarówno we współrzędnych światowych.
Całkowite liniowe przyspieszenie statku jest podane jako suma wartości t
dla każdego pędnika podzielona przez masę statku. Podobnie przyspieszenie kątowe jest po prostu sumą momentów obrotowych podzieloną przez moment bezwładności masy (który jest kolejnym skalarem). Statek się nie obróci, jeśli całkowity moment obrotowy wynosi zero. Podobnie nie porusza się, jeśli całkowity ciąg wynosi zero. Przypomnijmy, że moment obrotowy jest skalarem, ale ciąg (suma t
's) jest wektorem 2D.
Chodzi o to, że teraz możemy napisać nasz problem jako program liniowy . Powiedz najpierw, że chcemy, aby nasz statek zawrócił bez ruchu . Mamy zmienną dla każdego steru strumieniowego, $ x_1, x_2, ... $, która jest ilością ciągu, który zapewni ster. Jeden zestaw ograniczeń to:
0 <= x_i < fmax_i //for each i
gdzie fmax
jest maksymalna siła dla tego pędnika (pozwala nam to mieć mocniejsze lub słabsze). Następnie mówimy, że obie równości:
0 = Sum_i x_i * dir_i.x
0 = Sum_i x_i * dir_i.y
To koduje ograniczenie, że nie zastosujemy przyspieszenia liniowego, mówiąc, że całkowity ciąg jest równy zero (ciąg jest wektorem, więc po prostu mówimy, że każda część jest zerowa).
Teraz chcemy, aby nasz statek zawrócił. Przypuszczalnie chcemy to zrobić tak szybko, jak to możliwe, dlatego chcemy:
max (Sum_i x_i * c_i)
where c_i = <dir_i.x, dir_i.y, 0> CROSS <r_i.x, r_i.y, 0>
Rozwiązanie tych problemów przy x_i
jednoczesnym zaspokojeniu nierówności i równości powyżej, przy maksymalizacji powyższego podsumowania, da nam pożądany ciąg. Większość języków programowania ma dla nich bibliotekę LP. Po prostu włóż w to powyższy problem, a otrzymasz odpowiedź.
Podobny problem pozwoli nam poruszać się bez zawracania. Powiedzmy, że ponownie zapisujemy nasz problem w układzie współrzędnych, w którym chcemy poruszać się w dodatnim kierunku x. Zatem ograniczenia są następujące:
0 <= x_i < fmax_i //for each i
max Sum_i x_i * dir_i.x
0 = Sum_i x_i * dir_i.y
0 = (Sum_i x_i * c_i)
where c_i = <dir_i.x, dir_i.y, 0> CROSS <r_i.x, r_i.y, 0> // as before
Z ograniczeniem, że pędniki mogą wytwarzać pchnięcie tylko w jednym kierunku, będą ograniczenia dotyczące rodzajów obrotów i prędkości liniowych, które będziesz w stanie osiągnąć. Ujawni się to jako rozwiązanie 0 = x_1 = x_2 = ... = x_n
, co oznacza, że nigdy nigdzie się nie dostaniesz. Aby to złagodzić, sugeruję dodanie pary małych, słabych (powiedzmy 5% lub 10%) silników strumieniowych dla każdego gracza umieszczonego w 45 stopniach z każdej strony. Zapewni to rozwiązaniu większą elastyczność, ponieważ można je wykorzystać do przeciwdziałania słabym wtórnym efektom głównych silników odrzutowych.
Wreszcie, dla maksymalnie 100 silników odrzutowych, rozwiązanie LP jest wystarczająco szybkie, aby można go było wykonać na ramkę. Ponieważ jednak rozwiązanie nie zależy od położenia ani bieżącego stanu, można każdorazowo obliczyć rozwiązanie dla każdej rozsądnej kombinacji danych wejściowych kontrolera za każdym razem, gdy zmienia się kształt (obejmuje to dodawanie nierzutowych, które zmieniają moment bezwładności lub masę statku, ponieważ wtedy pędniki znajdują się w innym miejscu względem środka masy!). To 24 możliwości (tj. 8 kierunków razy {lewy obrót, brak obrotu, prawy obrót}).