Создание собственной системы стабилизации

ИльяПРо
rual:

На мой взгляд это пустой расход энергии, если регули позволят, а если не позволят, то они это вообще пропустят. ДИФФ-звено это демпфер от раскачки и больше ничего

Не соглашусь, ничего не пропустят, дифф часть через ФНЧ проходит, поэтому там не будет скачка, а вполне растянутый горбик, нормально регули отыграют. Это не только демпфер, но и ускоритель для быстрого отработки задания. К тому же в зависимости от того, как резко должен коптер реагировать на изменение задания отвечает этот самый коэффициент, который у меня равен 0,8. Сделать меньше - будет резче, сделать больше - коптер будет вести себя как вы хотите.

rual:

лексей, есть у него интеграл, просто он через два коэффициента TLT_ANG_P*RTE_ANG_I.

Интеграл то есть, но как Алексей сказал, если угловая скорость смещена, то есть ненулевая, при нулевой фактической скорости, то коптер никогда в горизонт не встанет, поэтому он предложил добавить еще интегральное звено в угловой контур.

rual:

Ничего не надо, будет медленная раскачка, двойной интеграл вносит большую задержку - очень тяжело настраивать. А в данном случае и не нужно.

Вот тут да, есть такой момент, вроде как из ТАУ вспоминаю, что запас устойчивости снижается. Но зато астатизм системы повышается.
Но все равно фиг с ним с этим интегралом, главное подавать несмещенные угловые скорости, тогда все нормально будет, а у меня так и есть.

rual
ИльяПРо:

Не соглашусь, ничего не пропустят, дифф часть через ФНЧ проходит, поэтому там не будет скачка, а вполне растянутый горбик, нормально регули отыграют. Это не только демпфер, но и ускоритель для быстрого отработки задания. К тому же в зависимости от того, как резко должен коптер реагировать на изменение задания отвечает этот самый коэффициент, который у меня равен 0,8. Сделать меньше - будет резче, сделать больше - коптер будет вести себя как вы хотите.

Делать-не делать, тут дело вкуса 😃 По мне (ещё раз повторюсь) смысл этого ДИФФ-звена - компенсация (демпфер) колебаний в следящей системе, вызванный фазовым сдвигом из-за задержки в цепи среда-обработка-реакция (угловая скорость-датчик-контроллер-ВМГ-угловая скорость). Быстродействия хватает и без него.

ИльяПРо:

если угловая скорость смещена, то есть ненулевая, при нулевой фактической скорости, то коптер никогда в горизонт не встанет, поэтому он предложил добавить еще интегральное звено в угловой контур.

Для того чтоб два интегральных звена работали последовательно надо иметь отрицательную обратную связь от средней точки (между ними), т.е. по угловой скорости. Но это и так делается, только в интеграторе (прогнозе) ФК.

ИльяПРо:

у меня на ПИД поступает скорость с ДУСа+биас (который калман считает, то есть все время обновляется), поэтому скорость поступает без смещения.

Зачем ещё одно звено?

ИльяПРо:

Но все равно фиг с ним с этим интегралом, главное подавать несмещенные угловые скорости, тогда все нормально будет, а у меня так и есть.

oleg70
ИльяПРо:

вроде как из ТАУ вспоминаю

Коллега…

ИльяПРо:

поэтому 20 процентов сигнала задания я подмешиваю в дифференциальную составляющую.

Мне ТАУ вспомнить в два раза сложнее )), но попробую тоже высказаться на этот счет - классический ПИД самодостаточен, все желаемые характеристики типа “скорости реакции” и т.п. достигаются тупо коэффициентами, а всякого рода “подмешивания” это скорей самообман… (ИМХО), т.е. у нас есть классическая “уставка” и “данные сенсора”, ладно, если подмешивать “нечто - третье”, а так - ходьба по кругу…
(возможно мой тезис можно было бы математически расписать, но уже слабо…)))

SergDoc

А на мой взгляд, всё не так
Я когда-то упоминал перевернуть ПИД с ног на голову и использовать в качестве пропорции самую точную часть показаний - угловую скорость, сейчас смотрю рейсеры как раз таким ПИД-ом и пользуются…

oleg70
SergDoc:

в качестве пропорции самую точную часть показаний - угловую скорость,

Ну это скорей к ПИД-у, как таковому, отношения не имеет, это просто замена одной величины регулирования на другую…,
, если я правильно понял идею - конечно, если углы из уг.скоростей не считать, то быстродействие регулятора растет.

SergDoc
oleg70:

если углы из уг.скоростей не считать, то быстродействие регулятора растет.

угол как раз будет интегральной составлящей, а диф - ошибка угловой скорости… можно конечно заморочится и высчитать ускорение… ещё одна бредовая мысль - с акселя взять центростремительное ускорение? оно ж вдоль осей…

oleg70
SergDoc:

ещё одна бредовая мысль - с акселя взять центростремительное ускорение? оно ж вдоль осей…

Везде шумы шумы и шумы, я не знаю как с ними бороться, а начинаешь бороться, все быстродействие насмАрку…

2 months later
ИльяПРо

Всем привет! Запилил новые 2 режима для фана.

Еще ко мне Dji Phantom 3 Advanced пришел. Первые впечатления, что довольно продуманы некоторые ньюансы. Векторного управления на движках я не заметил ,по-моему FOC должен себя иначе вести, но я не уверен. У подвеса обратная связь по положению ротора есть, отклонения отрабатывает плавно, без дребезга. Попробовал погазовать без винтов - коптер видит, что винтов нет, выводит сообщения. По яву - реагирует на угловую скорость, а не на положение. Однако в полете возвращается по яву.
Вообщем надо изучать. Удержание позиции работает четко и быстро, не плавает.
Будет время запилю тесты, сравнение.
Еще в планах попробовать отказаться от компаса вовсе и реализовать задумку с 2-мя ЖПС на диагонали для определения ориентации. Но это попозже

oleg70
ИльяПРо:

новые 2 режима

Как выглядят критерии “попадания” в заданную точку ?
Проверяется попадание текущего положения в некий квадрат или радиус ??

ИльяПРо

да, проверяется расстояние от текущего положения коптера до указанной точки, если оно меньше 0,4 м, то переходим в следующую точку. 0,4 м просто взял на глаз.
По идее сфера радиусом 0,4 м получается.

oleg70
ИльяПРо:

0,4 м, то переходим в следующую точку.

А курс на точку, я так понимаю, считается и корректируется постоянно в течении следования (?)…
Вообще, нельзя ли подсмотреть функцию пересчета положения по GPS в азимут точки ?? Для сравнения со своей:

int16_t get_azimut( float lat1,  float long1,  float lat2,  float long2)
{
float dlon_W, dlon_E,dphi, atn2,tc;
int16_t az;
int8_t sign;

	    dlon_W = (long2 - long1) - (2*PI*(floor((long2 - long1)/(2*PI))));
	    dlon_E = (long1 - long2) - (2*PI*(floor((long1 - long2)/(2*PI))));
	    dphi = log((tan((lat2/2) + (PI/4)))/(tan((lat1/2) + (PI/4))));

	    if (dlon_W < dlon_E) {
	        dlon_W = -1*dlon_W;


	        if (dlon_W >= 0)
	            sign = 1;
	        else
	            sign = -1;

	        if (abs(dlon_W) >= abs(dphi)) {
	            atn2 = (sign * PI/2) - atan(dphi / dlon_W);
	        }
	        else {
	            if (dphi > 0) {
	                atn2 = atan(dlon_W / dphi);
	            }
	            else {
	                if ((-1*dlon_W) >= 0) {
	                    atn2 = PI + atan(dlon_W / dphi);
	                }
	                else {
	                    atn2 = (-1*PI) + atan(dlon_W / dphi);
	                }
	            }
	        }
	    }
	    else {

	        if (dlon_W >= 0)
	            sign = 1;
	        else
	            sign = -1;

	        if (abs(dlon_E) >= abs(dphi)) {
	            if (dlon_E > 0)
	                atn2 = sign * PI/2 - atan(dphi / (dlon_E));
	            else
	                atn2 = 0;
	        }
	        else {
	            if (dphi > 0) {
	                atn2 = atan((dlon_E) / dphi);
	            }
	            else {
	                if ((dlon_E) >= 0) {
	                    atn2 = PI + atan((dlon_E) / dphi);
	                }
	                else {
	                    atn2 = (-1*PI) + atan((dlon_E) / dphi);
	                }
	            }
	        }

	    }


tc = atn2 - (2*PI*(floor((atn2)/(2*PI))));


az=tc*toGRAD;
if(az<0){az+=360;}
if(az>359){az=0;}
return az;
}
ИльяПРо

Если вы про курс носа коптера, то он вообще отвязан, я им управляю с пульта.

У меня при первом хорошем приеме ЖПС высчитываются коэффициенты для пересчета из градусов долготы и широты в метры. Далее все считается в метрах от старта

Вот это обработка в прерывании по приему GPS:

	if ((GPS_satellits > 8)&&(GPS_pDop<175))
	    {
		if (flag_start_home == 0)
		    {
			double LAT;
			flag_start_home = 1;
			GPS_height_start = GPS_height;
			GPS_lon_start = GPS_lon;
			GPS_lat_start = GPS_lat;
			LAT = (double)GPS_lat/10000000.0f;
			navUkfCalcEarthRadius(LAT, &KX, &KY);

		    }
		xSemaphoreTake(xGPS_UKF_Mutex, portMAX_DELAY);

		GPS_X = ((float)(GPS_lon-GPS_lon_start))*KX;
		GPS_Y = ((float)(GPS_lat-GPS_lat_start))*KY;
		GPS_alt = ((float)(GPS_height-GPS_height_start))*0.001f;

		xSemaphoreGive(xGPS_UKF_Mutex);

		StateNavUKF &= ~UKF_BAD_GPS;

		flag_get_pvt = 1;
	    }

сама функция персчета, взята у автоквада:

static void navUkfCalcEarthRadius(double lat, float *k_x, float *k_y) {
    double sinLat2;

    sinLat2 = sin(lat * (double)DEG2RAD);
    sinLat2 = sinLat2 * sinLat2;

    *k_y = (double)NAV_EQUATORIAL_RADIUS * (double)DEG2RAD * ((double)1.0 - (double)NAV_E_2) / pow((double)1.0 - ((double)NAV_E_2 * sinLat2), ((double)3.0 / (double)2.0));
    *k_x = (double)NAV_EQUATORIAL_RADIUS * (double)DEG2RAD / sqrt((double)1.0 - ((double)NAV_E_2 * sinLat2)) * cos(lat * (double)DEG2RAD);
    *k_y /=10000000.0f;
    *k_x /=10000000.0f;
}
oleg70
ИльяПРо:

Если вы про курс носа коптера

Я про нахождение вектора движения от одной точки к другой (его же надо считать, независимо от “носа” аппарата) или я че туплю ?

ИльяПРо:

высчитываются коэффициенты для пересчета из градусов долготы и широты в метры.

короче, упрощенный вариант математики, - приближаем поверхность к плоскости… (я понял).

ИльяПРо
oleg70:

короче, упрощенный вариант математики, - приближаем поверхность к плоскости… (я понял).

А я уже не понял. А как иначе?
Я понимаю так: вот например есть у нас две точки, у каждой точки долгота и широта. Нам надо узнать вектор, соединяющий первую точку со второй. Возьмем за начало отсчета первую точку. Находим коэффициент пересчета долготы в метры, он зависит от широты, при этом коэффициент из широты в метры постоянен, вроде (в упрощенном варианте). Далее вычитаем из второй точки первую по градусам. Умножаем полученные коэфициенты на разницу в градусах и получаем разницу в метрах, то есть наш вектор.
Та функция navUkfCalcEarthRadius считает уже не просто сферу, а элипсоид, но принцип тот же.
А как иначе? Или я не о том?

oleg70
ИльяПРо:

А как иначе?

Моя функция принимает координаты двух точек по GPS в радианах (текущая позиция и целевая позиция) а на выходе выдает честный азимут в градусах (угол от направления на север) из текущей точки на целевую… математика была взята мной давно с какого то геодезического сайта (уже не помню) там как бы всё с учетом тонкостей “большой сферы”…
На практике еще не испытывал, потому и интересуюсь - как другие люди делают…
Есть просто мое предположение, что при упрощенном подходе ошибка расчетов будет расти с увеличением дальности…
(Надо в поле походить и посмотреть на практике…)

ИльяПРо

В любом случае нужно знать не только азимут, но и расстояние до точки в метрах по двум осям. В том коде, что я привел, расстояния высчитываются, а угол можно узнать через atan2f(GPS_Y, GPS_X).
В моем подходе, ошибка будет от несовпадения элипсоида и геоида, а также как вы правильно заметили, что чем дальше от места старта, тем больше ошибка. Но на практике чтоб ошибка хоть как то повлияла, надо от точки старта перпендикулярно линии экватора двигаться километров 100-200 в моей местности. Если вы делаете совсем универсальный аппарат, и он может за один полет пролететь такое расстояние либо вы будете летать на полюсах, то можно каждый раз при приеме ЖПС сигнала делать пересчет коээфициентов.

oleg70
ИльяПРо:

В любом случае нужно знать не только азимут, но и расстояние до точки в метрах по двум осям.

Зачем ?? если сразу есть угол на точку…

ИльяПРо:

надо от точки старта перпендикулярно линии экватора двигаться километров 100-200

учитывая разрядность <float>, предположу, что ошибка будет видна на гораздо меньших расстояниях… (хотя, что спорить, проверять надо…)

ИльяПРо
oleg70:

Зачем ?? если сразу есть угол на точку…

Так когда остановится надо, если мы прост полетим в данном направлении? Это раз. Во-вторых, как вы будете зная только направление к точке вводить задание на ПИД , в простом случае - надо что-то типа задатчика интенсивности, типа апереодического звена с насыщением. У меня уже кубический интерполятор стоит, тут без знания расстояния не получится кривые разгона задать и скорости.
ошибка во float есть, но она константа и от расстояния не меняется. Можете проверить перевести градусы из дабла во флоат - потом пересчитать в метры, ошибка будет 10-30 см. Для задания точек, это не существенно. Для ОС удержания позиции существенна, поэтому у меня сначала вычитаются координаты в int32, а потом умножаются на коэффициенты пересчета…

oleg70
ИльяПРо:

Так когда остановится надо

Согласен, расстояние также желательно (но не обязательно)…

ИльяПРо:

Можете проверить перевести градусы из дабла во флоат - потом пересчитать в метры

Верю на слово. (скорей на выложенное видео полетов…, нет вопросов…)

Samer

Я тоже перешел из градусов в метры. У меня на ардуине крутится софт который считывает протокол GPS.
Она все обрабатывает и по I2C передает на другую . Для контроллера полета ,GPS такой же датчик как и аксель , в готовом виде принимает X,Y, высоту,скорость,курс,число спутников. И в протоколе идет только GGA. Чтоб передать дробную часть метров я умножаю расстояния на 10, (растояние тип long ) а контроллер делит на 10.

rual
ИльяПРо:

Запилил новые 2 режима для фана.

Отлично! Центр круга, относительно которого берется направление, фиксируется при включении режима?
Илья, я тебе пару вопросов в скайп написал.