Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save cocolacre/c6bbd01b05cf5132d616d6f9d762c336 to your computer and use it in GitHub Desktop.
Save cocolacre/c6bbd01b05cf5132d616d6f9d762c336 to your computer and use it in GitHub Desktop.
Предположим, что при достижении стола - показания высоты h1_laser_latest
с лазера сразу уменьшаются на величину, равную высоте стола.
{1.5, 1.5,1.5,1.5,1.5,1.5,1.5, 0.8 ,0.8,0.8}
Чуть обобщим задачу - допустим (не строго, как обезьяна, т.е. то буду принимать во внимание наличие точных чисел в задаче,
то не буду, а там разберемся на втором круге решения.),
конкретные размеры участков траектории\координаты и форма препятствий нам не известны.
(не будем же мы хардкодить выход за константные значения).
bool ABOVE_OBSTACLE = True;
... прочие инициализации;
Начинаем цикл.
Храним собранные "окном" последние Х показаний с обоих датчиков, в структуре типа LIFO
примерный вид структуры:
(например 10 элементов в массиве)
при получении нового значения - смещаем элемент по индексу [1]
в адрес [0]-го элемента, [2]-й - в [1]й адрес и тп.
Т.е. самое старое значение заменяется значением, полученным вслед за ним.
Самое свежее - смещается с [9] на [8], в [9] пишется новое значение.
int(or void) push:
chain_move_elements();
int append(*new_reading):
arr[9] = new_input;
int h1_10_avg = latest_10_averaged_height_measured_via_laser;
int h2_10_avg = latest_10_averaged_height_measured_via_pressure;
На каждом шаге - считаем разницу между этими средними.
int latest_10_averaged_delta_h1_h2 = 0;
Храним массив последних дельт.
int latest_10_normed_h1_h2_deltas[10] = {0,0,0,0,0,0,0,0};
Ищем в ряду "скачок" - момент, когда среднее значение данных с лазера начнет расти в сравнении с данными барометра.
запоминаем последнее значение высоты, полученное до начала "скачка".
int latest_surely_correct_coherent_h_as_if_h1_equals_h2;
(т.е. обновляем его, если не наступило состояние подозрения
о наличии препятствия, дельта высот с обоих датчиков стабильна)
Если превышен порог "производной" - начинаем подозревать
(ставим один из флагов, мол достингуто препятствие.)
if (abs(latest_10_normed_h1_h2_deltas[8] - latest_10_normed_h1_h2_deltas[9]) >
abs(latest_10_normed_h1_h2_deltas[7] - latest_10_normed_h1_h2_deltas[8])) {
res = suspicion_obstacle_beneath();
if res > THRESHOLD:
ABOVE_OBSTACLE_1 = True;
{!!!} В месте цикла, где мы задаём тягу (пишем в пин драйвера)
Перестаём учитывать показания с лазера (занижаем\зануляем вес,
иными словами "коэфициент доверия датчику")
//const int zero_trust = 0;
//const int some_trust = 0.5;
//const int full_trust = 1.0;
THRUST_LASER_TRUST = zero_trust;
THRUST = THRUST_LASER_TRUST * towards_target_h * laser_signal;
}
(+проверку: остались ли стабильны показания h2_latest_10_pressure:
это подтвердит гипотезу начала пролёта над препятствием)
Не забываем зафиксировать значение
h1_laser_latest_stable -
до начала отклонения показаний лазера от среднего h1 на предыдущих шагах.
Если позволяет алгоритм (т.е. если c момента резкого падения h1_laser_latest
тяга начинает расти с задержкой хотя бы в пару-тройку шагов),
(или вносим это изменение сами)
Если ABOVE_OBSTACLE_1 {
Т.к. по условию задачи показаний одного лишь барометра хватит, что бы
сохранять безопасную над столом высоту -
мы можем временно перестать учитывать показания с лазера,
продолжая полёт на текущей высоте по барометру т.е. без изменения тяги
(приповерхностными аэродинамическими эффектами пренебрегаем
для микродрона на высоте >0.5м над столом)
}
Берём получившуюся величину скачка h1_laser (равную высоте стола)
и начинаем вычитать её из поступающих с лазера значений.
И!
начинаем следить, занулилась ли разница между h1 и h2.
Если стабилизировалась и занулилась - значит мы точно над столом.
Снова начинаем учитывать заслужившим доверие h1_laser_latest
при контроле тяги, но теперь вычитаем обнаруженную высоту-ступеньку.
Как считать вес вклада датчика в тягу?
например:
A_w = 1.0
B_w = 0.5
C = U(F(A, A_w),F(B, B_w))
A = 3
B = 2
(HELP PLZ SEMANTIC NEURONS)
How C is closer to A is proportional to how A_w is closer to 1.0
...
C is twice closer to A than to B.
Hence С = 2.66
(1.0 - A_w)
(1.0 - B_w)
abs((C - A)/(C-B)) ≈ abs((1 - A_w)/(1 - B_w))
Therefore C:
(пренебрежём знаками, огрубим:)
(вспоминаем: Аль-джебр, Аль-мукабала!)
С - A = (C-B) * (1-A_w) / (1-B_w)
C = C * ((1-A_w)/(1-B_w)) - B * ((1-A_w)/(1-B_w))
С * (1 - ((1-A_w)/(1-B_w))) = B*((1-A_w)/(1-B_w))
C = B*((1-A_w)/(1-B_w)) / (1 - ((1-A_w)/(1-B_w)))
C ≈ THRUST.
A_w,B_w ≈ вес показаний с лазера,барометра.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment