может я слегка заблуждаюсь, и степень открытия клапана не влияет на силу, а только на количество жидкости. Т.е. тут у нас сила это напряжение, а количество - это сила))) Но все равно ускорение будет зависеть от силы, и будет падать при приближении пропускной способности крыльчатки мотора к скорости потока.
я сидел в кабине такого красавца, у меня не абстрактные представления что именно ТС хочет сделать )))
да я тоже картинки смотрел давно, все трактора были с джойстиками для периферии и с рулем для управления. Руль в целом из-за большего размера и самого принципа кручения с центрированием позволяет более точно управлять.
Ну как бы соберет ТС на джойстике - не понравится. Закажет многооборотный потенциометр и сделает руль, тож мне проблема. Ему бы алгоритм управления правильный сделать.
а программисты на что )))
если правильно понял идеологию форума, с таким подходом можно отъехать в “скетч нахаляву” )))
ТС помогите разобраться в гидродинамике, я в этой теме ноль без палочки.
Как на данный момент понимаю я:
- Сила потока (считай давление) зависит от производительности компрессора на бензомоторе
- Скорость потока зависит от минимального сечения трубы, т.е. определяется зазором, на который открыт клапан в первую очередь, и “проходимостью” гидромоторов во вторую очередь
- Когда на гидромотор подается давление, на его крыльчатку действует сила, пытаясь раскручивать ее
- Если силы потока достаточно чтобы преодолеть трение качения, то мотор раскручивается с соответствующим ускорением (зависит от кучи факторов типа сцепления с покрытием и массы трактора…)
- Когда гидромотор приближается к скорости, соответствующей скорости потока при текущем зазоре клапана, то сила на крыльчатку падает, т.к. для потока контур крыльчатки раскрученного мотора близок по свойствам к прямоточной трубе. В этот момент поток сталкивается с лишь небольшим сопротивлением, вызванным трением качения в ходовой части, уклоном дороги и сопротивлением воздуха, действующего на трактор.
Всё верно вроде?
И еще вот целиком “псевдокод” алгоритма, который прочитает управление и вычислит значения для клапанов (упростил и дополнил то, что писал выше)
// это калибровки джойстика (минимум, центр, максимум), они для каждой оси могут быть разные
// можете замерить 1 раз и вписать в программу, можете потом всетаки реализоввать калибровку, как я очень советую
джойстикДоУпораВперед = 390
джойстикВпередНазадЦентр = 510
джойстикДоУпораНазад = 630
джойстикДоУпораВлево = 340
джойстикВлевоВправоЦентр = 500
джойстикДоУпораВправо = 611
// это отклонения джойстика от центра, которые будут игнорироваться
// нужно чтобы избегать нежелательные срабатывания
игнорируемыеОтклонения = 10
// пересчитываем начало интервалов для каждой оси, с учетом калибровки центров и игнорируемыеОтклонения
// эта часть вычислит правильно независимо от того, в цифрах джойстикДоУпораВперед больше или меньше чем джойстикДоУпораНазад (и так же для лево-право)
джойстикМинимальноВперед = джойстикДоУпораВперед > джойстикВпередНазадЦентр ? джойстикВпередНазадЦентр + игнорируемыеОтклонения : джойстикВпередНазадЦентр - игнорируемыеОтклонения
джойстикМинимальноНазад = джойстикДоУпораНазад > джойстикВпередНазадЦентр ? джойстикВпередНазадЦентр + игнорируемыеОтклонения : джойстикВпередНазадЦентр - игнорируемыеОтклонения
джойстикМинимальноВлево = джойстикДоУпораВлево > джойстикВлевоВправоЦентр ? джойстикВлевоВправоЦентр + игнорируемыеОтклонения : джойстикВлевоВправоЦентр - игнорируемыеОтклонения
джойстикМинимальноВправо = джойстикДоУпораВправо > джойстикВлевоВправоЦентр ? джойстикВлевоВправоЦентр + игнорируемыеОтклонения : джойстикВлевоВправоЦентр - игнорируемыеОтклонения
void loop() {
// это мы получаем "сырые" показания с датчиков холла (оси джойстика) как есть
джойстикПердЗад = analogRead(пинВпередНазад)
джойстикЛевоПраво = analogRead(пинВлевоВправо)
// нормализуем значения
// функция map() нам пропорционально приведет занчение с холла из интервала джойстикМинимальноВперед..джойстикДоУпораВперед к интервалу 0..255
// но эта функция позволяет выходить за рамки интервала, если джойстикПердЗад не лежит в пределах джойстикМинимальноВперед..джойстикДоУпораВперед
// и получится значение за пределами интервала 0..255
// поэтому используем функцию constrain(), которая обрежет результат выполнения map() до нужных 0..255
впередНормализовано = constrain(map(джойстикПердЗад, джойстикМинимальноВперед, джойстикДоУпораВперед, 0, 255), 0, 255)
// все те же вычисления для остальных полуосей джойстика, только со своими интервалами
назадНормализовано = constrain(map(джойстикПердЗад, джойстикМинимальноНазад, джойстикДоУпораНазад, 0, 255), 0, 255)
влевоНормализовано = constrain(map(джойстикЛевоПраво, джойстикМинимальноВлево, джойстикДоУпораВлево, 0, 255), 0, 255)
вправоНормализовано = constrain(map(джойстикЛевоПраво, джойстикМинимальноВправо, джойстикДоУпораВправо, 0, 255), 0, 255)
// теперь у вас нормализованные значения 0..255, на их основе можно вычислить степень открытости клапанов
// причем по одной оси только одно значение сможет быть больше нуля, если джойстик был отклонен
если (впередНормализовано > 0 или назадНормализовано > 0) {
// есть движение вперед или назад, повороты замедлением одной стороны
левыйПереднийКлапан = constrain(впередНормализовано - влевоНормализовано, 0, 255)
правыйПереднийКлапан = constrain(впередНормализовано - вправоНормализовано, 0, 255)
левыйЗаднийКлапан = constrain(назадНормализовано - влевоНормализовано, 0, 255)
правыйЗаднийКлапан = constrain(назадНормализовано - вправоНормализовано, 0, 255)
} иначе {
// нет движения вперед или назад
// ща будет прикольно:
левыйПереднийКлапан = вправоНормализовано
правыйПереднийКлапан = влевоНормализовано
левыйЗаднийКлапан = влевоНормализовано
правыйЗаднийКлапан = вправоНормализовано
// помните, да, что у вас только одно из влевоНормализовано и вправоНормализовано может быть НЕ равно нулю?
// вот вам и танковый разворот без доп. оси джойстика
}
// тут вывод нового ШИМ на клапаны
analogWrite(пинЛевыйПереднийКлапан, левыйПереднийКлапан)
analogWrite(пинПравыйПереднийКлапан, правыйПереднийКлапан)
analogWrite(пинЛевыйЗаднийКлапан, левыйЗаднийКлапан)
analogWrite(пинПравыйЗаднийКлапан, правыйЗаднийКлапан)
}
Это по принципу, который вы хотите, с которым я не согласен, но навязывать иное не моё дело. Если (когда) поймете математику и логику, можно будет и в код программы перегнать
эта наука предельно детерминирована, там формулы есть.
ну я догадываюсь. Но общие тезисы верны или нет?
П.с. еще немного упростил “псевдокод” в предыдущем сообщении, убрав лишние условия, которые итак функциями учтутся
П.п.с. Предлагаю обдумать возможность сделать для джойстика ограничительные направляющие типа такой (вид сверху, красное это ось ручки джойстика)
Это чтобы нельзя было случайно на танковый разворот или в реверс уходить, минуя центральное положение
терминология не соответствует, с точки зрения науки о гидроприводе это не тезисы, это разговор под водочку в гараже, тут же пробовать, ломать, по новой пробовать и теде.
Доброго всем дня!
Только проснулся сколько всего интересного. Первое по поводу халявы. Вы знаете я с радостью готов и заплатить. Хотя и охота разобраться самому. Другое дело ч времени на все не хватает. И я выложил мой почтовый ящик. Даже пару курсов бы взял. Т.к. читаешь книгу и возникает в примерах вопрос а где само значение например или в качестве примера не стали писать а ты голову ломаешь. Ну и есть интерес разобраться в этом. Книгу основы ещё не дочитал и она реально лучше профессиональной работы. Географически я в Новосибирске. И буду рад встречи и покажу и расскажу. К тому же климат контроль я все таки тоже хочу с помощью Ардуино делать.
Теперь по поводу ШИМ сигнала. Человек который мне дал схему, сказал что да на длине импульса.
это лучшее решение, т.к. это ваш проект, будет возможность самостоятельно менять в угоду личным предпочтениям.
Как вариант, просто отдельную ардуину взять для климата. Они в разрезе проекта копеечные, и пусть каждая за своё отвечает.
Пламенный привет с Южно-Сахалинска
вот нужны подробности… Клапаны через транзистор ожидают таки сигнал, где важна частота ШИМ, минимальная и максимальная длины импульса? Или всетаки они с транзистора “прерывистую” подачу напряжения воспринимают как просто напряжение, а от “пропусков” между импульсов зависит, насколько это напряжение высоко или низко?
По поводу работы гидравлики. Схема придумана так что есть магистраль высокого давления с гидроаккумулятор. И да чем больше откроешь клапан гидрораспределителя тем больше жидкости на выходе. Саленоиды управляют не клапанами напрямую а управляющим каналом давлени жидкости. То есть они приоткрывают маленький канал с жидкостью а он в свою очередь управляет уже основным соленоидом. Это в крации.
Но так как скорость реакции хорошая. Я не исключаю что при полной скорости вперёд дёрнув джойстик назад можно вылететь или даже перевернутся. Поэтому должна быть задержка на хотя бы резкие изменения или просто ограничить скорость изменения. Создать искусственную инертность. То же касается остановки.
вот поэтому я бы предпочел чтобы МК знал реальные скорости вращения колес. Расчетные (ожидаемые) могут не соответствовать действительности по разным причинам
Ну и я наконец добрался до компьютера.
Сейчас буду пробовать писать хоть что-то.
Просто вопрос колибровки. У меня есть сейчас программа которую я выкладывал в начале. Она измеряет показания одного датчика холла. Я могу по очереди подключить все три датчика и записать показания. Или лучше все таки сразу на все три датчика настраивать.
Если на все три я сейчас здесь напишу подскажите пойдет так или нет.
то-есть на вертолёте петлю Нестерова делал? )))
int Led = 13 ;
const int hall_1Pin_analog = A0; // Пин датчика Холла 1 (вперед/назад)
const int hall_2Pin_analog = A1; // Пин датчика Холла 2 (поворот)
const int hall_3Pin_analog = A2; // Пин датчика Холла 3 (вращение)
const int valve_APin = 9; // Пин для управления электромагнитом A (вперед левая)
const int valve_BPin = 10; // Пин для управления электромагнитом B (вперед правая)
const int valve_CPin = 11; // Пин для управления электромагнитом C (назад левая)
const int valve_DPin = 12; // Пин для управления электромагнитом D (назад правая)
int val ;
void setap ()
{
pinMode ( Led, OUTPUT) ;
Serial.begin ( 9600 ) ;
}
void loop ()
{
Serial.println (analogRead (hall_1Pin_analog, hall_2Pin_analog, hall_3Pin_analog )) ;
}

