Ну это все, что именно я могу предложить
Я знаю о существовании той статьи, потому даю ссылку, но на практике мне работать с этой камерой не приходилось, потому качество и достоверность этого материала мне не известны.
Всем доброго дня
Представляю вниманию разработчиков фрагмент кода, реализующий ограничение тягового усилия локомотива в зависимости от скорости и позиции контроллера позиций. На эту тему уже есть
статья, но некоторые утверждения из неё с читаю ошибочными и спорными, поэтому вот альтернативный вариант.
Принцип вычисления тяги заключается в том, что для каждого значения текущей скорости сопоставляется уровень тяги, развиваемой локомотивом. В идеале должно быть столько пар "скорость - тяга", сколько может быть значений скорости, включая дробные значения. Но это очень много, поэтому применяется метод, сходный с усреднением при оцифровке аналогового сигнала. Весь диапазон скорости (от 0 до максимальной) делится на несколько участков (чем больше, тем лучше, как и битрейт). Потом берутся крайние точки скорости по краях участка, рассчитывается, на каком "расстоянии" от меньшего значения находится текущая скорость. Применив значение "расстояния", можно определить, насколько надо сместиться между крайними точками тяги.
Думаю, теории достаточно. Мне трудно передать эти мысли без рисунков, а рисовать, не имея уверенности, что это кому-нибудь действительно интересно, я не очень хочу
Первопроходец этого метода - Максим ака Supermax. Если я ошибаюсь, поправьте меня, пожалуйста, я исправлю.
Моя роль в этом коде - его упрощение и трансформация в функцию, которую можно без правок использовать в любом скрипте, просто скопировав. Единственное, что надо подгонять в каждом локомотиве - таблицу тяги.
В блоге, ссылку на который я привожу, показано, что собой представляет таблица и какие правки необходимо сделать в файлах
Tractive Effort VS Speed , Tractive Effort vs Throttle, поэтому я не буду повторяться.
Вот функция:
Код: Выделить всё
function TractionValue(currentSpeed, PosThrottle)
local MaxSpeed = 0
local TrDownLim, TrUpLim, SpUpLim, SpDownLim = 0, 0, 0, 0
local TractionPercent = 0
for k,v in ipairs(POS_S[PosThrottle]) do
if(v ~= nill) then
MaxSpeed = v
else
break
end
end
if currentSpeed < MaxSpeed and PosThrottle > 0 then
for k,v in ipairs(POS_S[PosThrottle]) do
if(v < currentSpeed) then
TrDownLim = POS_T[PosThrottle][k]
SpDownLim = v
else
TrUpLim = POS_T[PosThrottle][k]
SpUpLim = v
break
end
end
TractionPercent = (TrDownLim + (1 - (SpUpLim - currentSpeed) / (SpUpLim - SpDownLim)) * (TrUpLim - TrDownLim))
else
TractionPercent = 0
end
return TractionPercent/100
-- Call( "*:SetControlValue", "Regulator", 0, TractionPercent/100);
end
Для использования функции необходимо скопировать её в любое место скрипта. Вызов производится из функции
Update. Как правило, в функции
Update используются данные о позиции регулятора тяги и о текущей скорости, поэтому я не привожу их вычисление, думаю, за этим дело не станет. Вызывается функция
TractionValue(А, В) в зависимости от того, как будет использоваться результат её работы дальше. Если значение сразу передается на системный контрол тяги, то нужно раскомментировать строку
Код: Выделить всё
Call( "*:SetControlValue", "Regulator", 0, TractionPercent/100);
и закомментировать ту, что выше. Тогда вызов имеет такую форму:
где А - это текущая скорость, В - позиция.
Если же дальше надо будет проводить ещё какие-то вычисления (шунтирование, блокировки или т.п.), то функцию править не надо, а вызов будет иметь такую форму:
где Tr_Percent - результат вычисления, который возвращается. А - это текущая скорость, В - позиция.
В процессе работы функция использует массивы пар "скорость - тяга", которые нужно составить к конкретной модели по её графику ТХ. Структуру функции, содержащей эти, а также вспомогательные таблицы, я представляю на примере разработанной мной к ТЭМ2:
Код: Выделить всё
function TractionValueTab()
POSITION1_S = {0, 2, 4, 6, 8, 10}
POSITION1_T = {12, 8.5, 5.7, 2.8, 1.4, 0}
POSITION2_S = {0, 2, 4, 6, 8, 10, 15, 20}
POSITION2_T = {24, 19, 14.2, 10, 7, 3.5, 1.4, 0}
POSITION3_S = {0, 2, 4, 6, 8, 10, 15, 20}
POSITION3_T = {75, 48.5, 20, 14, 8.5, 4.2, 1.5, 0}
POSITION4_S = {0, 2, 4, 6, 8, 10, 15, 20, 30, 40}
POSITION4_T = {100, 53.5, 36, 25, 21.4, 14, 10, 6.4, 3.2, 0}
POSITION5_S = {0, 2, 4, 6, 8, 10, 15, 20, 30, 40, 50, 60}
POSITION5_T = {100, 100, 50, 45, 35.7, 21.4, 15, 11.4, 8.5, 5.7, 3.5, 0}
POSITION6_S = {0, 2, 4, 6, 8, 10, 15, 20, 30, 40, 50, 60, 70}
POSITION6_T = {100, 100, 92, 70, 50, 32, 24, 15.7, 11.4, 8.6, 5.7, 2.1, 0}
POSITION7_S = {0, 2, 4, 6, 8, 10, 15, 20, 30, 40, 50, 60, 70}
POSITION7_T = {100, 100, 100, 82, 66, 37, 30, 22.8, 15, 10.7, 7.7, 3, 0}
POSITION8_S = {0, 2, 4, 6, 8, 10, 15, 20, 30, 40, 50, 60, 70}
POSITION8_T = {100, 100, 100, 90, 67, 45, 35.7, 23.5, 17.1, 13.5, 10, 5, 0}
POS_S = {POSITION1_S, POSITION2_S, POSITION3_S, POSITION4_S, POSITION5_S, POSITION6_S, POSITION7_S, POSITION8_S}
POS_T = {POSITION1_T, POSITION2_T, POSITION3_T, POSITION4_T, POSITION5_T, POSITION6_T, POSITION7_T, POSITION8_T}
end
Тем, кто заинтересуется, рекомендую просматривать таблицы в NP или другом редакторе, не затирающем табуляцию, тогда хорошо видно парность аргументов таблиц.
В ТЭМ2 8 позиций, поэтому здесь 8 пар массивов "скорость - тяга", по одной паре массивов на каждую позицию. Последние 2 таблицы (POS_S и POS_T) - это ссылки на конкретные массивы в зависимости от того, номер какой позиции был передан при вызове функции
TractionValue(А, В).
Функция
TractionValueTab() вставляется в скрипт ниже функции
TractionValue(А, В).
Сильные люди - это не те, у которых всё хорошо, а те, у которых всё хорошо несмотря ни на что.