Skocz do zawartości

Sebo_b

Społeczność Astropolis
  • Postów

    740
  • Dołączył

  • Ostatnia wizyta

Treść opublikowana przez Sebo_b

  1. W komercyjnych projektach to zwykle nie możliwe A jeszcze jedno - pomimo załączonego kodu, wciąż uważam, że należy to zrobić na timerach hardwearowych.
  2. Jeśli miała by to być statyczna tablica, to wektor na niej byłby chyba już przesadą Rozwiązaniem pośrednim jest prealokacja tej tablicy w konstruktorze i (w przypadku tego co załączyłem) nie wołanie cleanup. PS: STL że względu na intensywne użycie template'ów jest dość ciężki dla footprintu (wielkość binarki). Szczególnie jeśli jest to nie optymalizowana wersja, w pełni zgodna ze standardem. Dlatego często unika się STLa w embedded i pewnie dlatego implementacje możecie znaleźć tylko na githubie a nie dołączoną do kompilatora.
  3. @r.ziomber jeszcze komentarz do Twojego kodu, taki high level na szybko: - brak enkapsulacji - zmienne w def funkcji powinny byc self-explanatory - usuwanie z tablicy jest bardzo nieefektywne, przesuwasz za kazdym razem ogon o jeden, robisz dużo reallocow (zobacz jak to jest u mnie) - złożoność masz tam O(n^2) + złożoność realloca + fragmentacja pamięci - ogólnie w embedded należy przyjąć ze malloc/realloc/free są drogie i optymalizować ich użycie - zwracasz id taska a pozniej usuwasz z tablicy, idki na zewnątrz będę wskazywały błędne taski Gdyby się wczytać to jest tego dużo więcej.
  4. Nie rozumiem, w którym miejscu? To jest oczywiście kolejny krok, wydzielenie kolekcji na zewnątrz. Ale z drugiej strony jest to taka prosta struktura, że można pominąć.
  5. Na szybko zrefaktorowałem Twój kod, a w sumie to napisałem go od nowa zachowując logikę. Nie testowałem tego kodu (tylko syntax), więc jest pewnie sporo bugów. Ale wyłapanie bugów to dobre ćwiczenie #include <limits.h> #include <cstdlib> class Timer { public: typedef void(*Callback)(void*); Timer(); ~Timer(); /** * count < 0 for unlimited execution * returns task number or 0 if fail; **/ size_t addTask(long delay, long interval, int count, Callback callback, void* cbParam); void removeTask(size_t taskId); void run(); void cleanUp(); private: struct Task { long interval; unsigned long nextCall; int count; size_t taskId; Callback cb; void* cbParam; }; Task* tasks; size_t tasksSize; size_t taskIdCounter; bool clean; unsigned long nextCall; }; Timer::Timer(): tasks(NULL), tasksSize(0), clean(true), nextCall(ULONG_MAX), taskIdCounter(0) { } Timer::~Timer() { if (tasks) free(tasks); } size_t Timer::addTask(long delay, long interval, int count, Timer::Callback callback, void* cbParam) { if (count == 0 || callback == NULL || interval == 0) return 0; Task *t = NULL; unsigned long now = ::now(); if (!clean) { for (size_t i = 0; i < tasksSize; ++i) { if (tasks[i].count == 0) { if (t == NULL) { t = tasks+i; clean = true; } else { clean = false; } } } } else { Task* newTasks = static_cast<Task*>(realloc(tasks,(tasksSize+1)*sizeof(Task))); if (!newTasks) return 0; tasks = newTasks; t = newTasks + tasksSize++; } t->interval = interval; t->nextCall = now + interval + delay; t->count = count; t->cb = callback; t->cbParam = cbParam; t->taskId = ++taskIdCounter; if ( static_cast<long>(nextCall - t->nextCall) >= 0) nextCall = t->nextCall; return t->taskId; } void Timer::removeTask(size_t taskId) { // we don't need to update nextCall, in the worst case we end up with one empty loop in run() // unsigned long nextCallSoFar = ULONG_MAX; for (size_t i = 0; i < tasksSize; ++i) { if (tasks[i].taskId == taskId) { tasks[i].count = 0; clean = false; // if ( nextCall != tasks[i].nextCall) return; } // else if (static_cast<long>(nextCallSoFar - tasks[i].nextCall) >= 0) { // nextCallSoFar = tasks[i].nextCall; // } } // nextCall = nextCallSoFar; } void Timer::run() { unsigned long now = ::now(); if ( static_cast<long>(now - nextCall) >= 0 ) { for (size_t i = 0; i < tasksSize; ++i) { nextCall = ULONG_MAX; if (tasks[i].count != 0 && static_cast<long>(now - tasks[i].nextCall) >= 0) { tasks[i].cb( tasks[i].cbParam); if (tasks[i].count > 0 && --tasks[i].count == 0) clean = false; else tasks[i].nextCall = now + tasks[i].interval; } if ( static_cast<long>(nextCall - tasks[i].nextCall) >= 0) nextCall = tasks[i].nextCall; } } } void Timer::cleanUp() { if (clean) return; Timer *head = tasks, *tail = tasks + tasksSize - 1; while (head < tail) { if (head->count == 0 && tail->count != 0) { *head = *tail; tail->count = 0; } if (head->count != 0) ++head; if (tail->count == 0) --tail; } size_t newTasksSize = head-tasks; Task* newTasks = static_cast<Task*>(realloc(tasks,newTasksSize*sizeof(Task))); if (newTasks == NULL) return; // we basically keep it unclan tasks = newTasks; tasksSize = newTasksSize; clean = true; }
  6. Z tym co zaproponowane overflowy nie powinny mieć wpływu na średnie czasy - arytmetyka zadziała. Tutaj nie ma się co przekonywać, to trochę jak byś przyjechał z Anglii (pisanie w C) i twierdził, że musisz się przekonać do prawostronnego ruchu (C++) Piszesz w C++ to używać "pożądnych" castów. Co więcej, zaczniesz (lepiej nie) używać wielodziedziczenia i C casty się wysypią.
  7. Masz rację, że jest tam bug, a nawet dwa: 1. Overflow nextCall - tak jak napisałeś, now() będzie duże, nextCall małe 2. Overflow now() bo nie mamy pewności czy pod koniec zakresu zdąży się wykonać, czyli nextCall będzie duże, a now() małe To są dodatkowe cornercase'y, więc || a nie && w Twoim rozwiązaniu powinien to załatwić, tylko że pierwszy warunek zawiera się w tym co zaproponowałeś - więc wystarczyło by : if ( now() - nextCall < ULONG_MAX / 2 ) { // lub - bez dzielenia (choć to tylko estetyka w tym przypadku) if ( now() - nextCall < (ULONG_MAX >> 1) ) { // lub - moim zdaniem bardziej czytelnie if ( now() - nextCall < LONG_MAX ) // lub - bez użycia limits if ( now() - nextCall < (~0ul >> 1) ) // a ja bym napisał to tak, żeby było dla każdego czytelne (choć nie widać tak od razu, że obsługuje corner-case'y) if ( static_cast<long>(now() - nextCall) >= 0 ) {
  8. Też podejrzewałem, że sobie to kompensuje. Align na 3 gwiazdy daje wszystkie potrzebne do tego informacje.
  9. Z takich ciekawostek, guiding potrafi działać przez port ST4 albo właśnie bezpośrednio przez pule-commands do silników. Więc jest tak jak piszesz, ale z kamerą.
  10. Dzięki. Napisał tylko zamiast skomplikowanego mapowiania nieba używa do tego bardziej elastycznej metody i kamery - nazywa się PHD2
  11. W trybie AZ montaże AZEQ trackują w obu osiach Alt i Az - inaczej się nie da.
  12. Sebo_b

    M13

    Pracuję na Macu - więc mam bardzo ograniczony wybór softu. Gdyby Pixinsight kosztował z połowę tego co kosztuje to bym się pewnie skusił, teraz sporo jeszcze przede mną zanim zacznę odczuwać braki w używanych toolach. Jeśli dojdę do tego momentu, to pewnie zacznę stosować. Po niedzieli wracam do Wawy i moje hobby się mocno ograniczy, jechać po 50-100km ze sprzętem i stać z pół nocy na zimnie samemu... pewnie znowu teleskop wyląduje w szafie na długie miesiące Podeszłem teraz inaczej, Nebulosity tylko stack + stretch, reszta w Affinity. Kanały są wszystkie, nawet niebieskie gwiazdki wyszły, tylko znowu jakieś takie niebiesko-zielone to zdjęcie. Trochę szumu tła zostawione specjalnie dla @Pav1007
  13. Wciąż jest dużo, ale już coraz mniej. Oprócz pracy typowo dla elektronika: komórki od czasu iOSa i Androida to już nie embedded. Zostały telewizory, ale tam też coraz więcej Androida, więc jeśli nie pracujesz u SoC vendora (np MTK) to też nie embedded. Automotive się jeszcze broni rękami i nogami przed Googlem i Applem.
  14. Na Synscanie poniżej align na 3 gwiazdy jest Polar Alignment. Działa to tak: 1. Montaż ustawia się na jasnej gwieździe, np Arcturus 2. Prosi o dokładne ustawienie jej w środku pola (pilotem). PS: nie wiem czy znasz tę metodę, ale jeśli nie masz okularu z krzyżem, to rozogniskowanie pomaga w ustawieniu obiektu centrycznie (jest po prostu dużym kółkiem w okularze). 3. Przestawia o błąd w jednej osi i prosi o ustawienie śrubami (NIE pilotem). 4. Robi to samo dla drugiej osi. Po tym trzeba znowu wyalignować na 3 gwiazdy. Czasem procedurę powtórzyć, żeby mieć jeszcze dokładniej. Jeśli montaż będzie idealnie prowadził i będzie idealnie wypoziomowany - to obiekt będzie sztywno, niezależnie od alignowania. Alignowanie jest potrzebne tylko do GOTO*, procedurę alignowania można pominąć i kręcić ręcznie. * - nie mogę nigdzie znaleźć potwierdzenie / zaprzeczenia czy montaże SW EQ zawsze prowadzą tylko w jednej osi, czy może jak wykryje cone-error (brak poziomu) w czasie alignacji to pomaga sobie drugą osią. Mam podejrzenie, że sobie pomaga, bo wczoraj miałem żyletę na biegun (ustawiane softem) a obiekty po godzinie odjeżdżały, nie zauważyłem, że w menu był ustawiony cone-error z poprzednich alignów.
  15. Sebo_b

    M13

    Widziałem to - czerwony jest zgubiony gdzieś na wcześniejszym etapie (przed eksportem stacka do programu graficznego). Nie byłem w stanie go już odzyskać bez cofania się do początku.
  16. Sebo_b

    M13

    Nie mam flatownicy, sprzęt rozkładam po zmroku i składam przed świtem Więc posiłkuję się jak mogę. W drugiej próbie zrobiłem "ręcznie" syntetycznego flata. Dziś nauczyłem się jeszcze jednego, obrabiać należy w nocy / wieczorem, a nie w bardzo słoneczny dzień Jak teraz?
  17. Sebo_b

    M13

    @Zorg7 ja polecam Affinity Photo jako tańszą konkurencję PSa. Darmowy nie jest, ale cena bardzo konkurencyjna.
  18. Sebo_b

    M13

    Dzięki - mam jeszcze większa z asi290mc, jak uda mi się porządnie to złożyć to może nałożę sam środek. Co do "paprochów", to chyba znalazłem, synthetic flat fielder z Nebulosity dość mocno to wycina. Złożę na spokojnie jeszcze raz. Dzięki wszystkim za komentarze.
  19. Sebo_b

    M13

    Na pewno. Patrzyłem na Twoje zdjęcie przed publikacją - masz tam większy FOV, ale 1:1 każda punktowa (nie szare tło) gwiazda u Ciebie występuje też u mnie. Tylko @Pav1007 jak zwykle ma rację, że za bardzo pojechałem z tłem, dlatego się dość bardzo odcięły, niektóre mają po kilka pixeli. Załączam porównanie Twojego zdjęcia do mojego - 1:1 crop ze środka, nic nie modyfikowane. EDIT: forum wycina animowane PNG, wrzucam GIFa.
  20. Sebo_b

    M13

    Dzięki @wessel za zdjęcie referencyjne.
  21. Sebo_b

    M13

    Nie nałożyłem żadnej gwiazdki stemplem. Jestem też przeciwnikiem masek - choć tutaj dla dwóch placków zrobiłem wyjątek.
  22. Sebo_b

    M13

    EDIT: usunięte, bo tylko śmieci
  23. Sebo_b

    M13

    W tle nic już więcej nie ma, sprawdzałem - i chyba zaczynam lubić ciemne Niebieski też mi przeszkadzał, ale popatrzyłem na kilka innych zdjęć i tam chyba po prostu jest niebiesko...
  24. Sebo_b

    M13

    Dość oklepany obiekt, ale chciałem go powtórzyć w szerszym polu (wiem, i tak wąskie). Łapane wczoraj, księżyc prawie 90% ale o 23:30 już dość nisko, bo 10 st. MN190 / EQ6-R / Canon 40D / ISO400 / 120x30s + darki. EDIT: Po żywej dyskusji w wątku i pomocy wielu forowiczów (dzięki) podmieniam zdjęcie na trochę lepsze. Do ideału daleko - ale na razie muszę odpocząć od tego obiektu. Może się przesiądę na czarnobiałą kamerę bez filtrów
×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Umieściliśmy na Twoim urządzeniu pliki cookie, aby pomóc Ci usprawnić przeglądanie strony. Możesz dostosować ustawienia plików cookie, w przeciwnym wypadku zakładamy, że wyrażasz na to zgodę.