Информация: Уважаемые посетители! В течение нескольких месяцев на форуме существовала проблема с регистрацией новых пользователей, о которой администрации стало известно недавно. Если вы ранее пытались зарегистрироваться на форуме, но не получили на ваш e-mail письмо с ссылкой для подтверждения регистрации, просим вас зарегистрироваться повторно. Приносим извинения за доставленные неудобства. Если вы все еще испытываете проблемы с регистрацией на форуме, обратитесь за помощью на e-mail: mr.angelo@railroadsim.net

LuaScript - для RS

Другие вопросы и проблемы разработки дополнений

Re: LuaScript - для RS

Сообщение Света » 14.04.2017, 13:40

Приветствую всех :)

Выявлен странный и необъяснимый нюанс в работе функции "Update" скрипта симуляции локомотива.
Дело в том, что передаваемое в функцию значение интервала времени не соответствует действительности. На самом деле, это значение почему-то завышено в 2 раза. Причины пока непонятны.
Для решения этого недостатка мне показалось уместным применить конструкцию
Код: Выделить всё
function Update (interval)
   
   local simulationTime = Call("*:GetSimulationTime")   
   interval = simulationTime - prevST
   prevST = simulationTime

Вроде как все просто - использовать прямой просчет, который покажет, сколько времени прошло с последнего прохода функции. Те же данные, но полученные явным методом, независимо от движковых непоняток.
Но этот метод тоже может сделать пакость.
Если проехать на локомотиве, в котором используется такой прием, потом "пересесть" на другой состав, а затем снова взять управление первым составом, то игрока будет ждать сюрприз.
Скрипт симуляции работает только в составе игрока. Если состав покинуть, а потом снова захватить, скрипт проинициализируется заново. В результате все переменные получат стартовые значения.
А вызов Call( "*:GetSimulationTime") возвращает время, прошедшее с самого начала игры. Как следствие, в первый проход после второго захвата состава переменная interval получит значение, равное всему времени от начала управления этим составом. А это уже не доли секунд, а минуты, или даже часы.
Представьте, что будет со всеми таймингами, использующими для вычисления переменную interval, значение которой может быть в пределах тысячи.
Вроде как и небольшой баг, но у мне пришлось потратить полдня на то, чтобы понять, почему приборы зашкаливают при повторном захвате. Надеюсь, мой опыт поможет вам обойти эти грабли.
Забанена по собственному желанию. По важным вопросам связаться со мной можно через почту divovigna@gmail.com
Аватара пользователя
Света
 
Сообщения: 1338
Зарегистрирован: 18.06.2016, 19:38
Благодарил (а): 983 раз.
Поблагодарили: 1805 раз.
Играю в: Train Simulator Classic
Имя: Пандора

Re: LuaScript - для RS

Сообщение Skif » 14.04.2017, 14:02

У меня был похожий косяк с приборами, использующими дрожание стрелок. Решил принудительным сбросом счетчиков колебаний через несколько периодов, счетчики вынес в отдельный массив значений. Костыль, но работает.
Skif
 
Сообщения: 3750
Зарегистрирован: 01.10.2009, 17:42
Благодарил (а): 0 раз.
Поблагодарили: 2 раз.
Имя: Дмитрий

Re: LuaScript - для RS

Сообщение Света » 15.04.2017, 10:59

Skif писал(а):Решил принудительным сбросом счетчиков колебаний через несколько периодов, счетчики вынес в отдельный массив значений. Костыль, но работает.

Skif писал(а):
Код: Выделить всё
TremorCounter = {      -- счетчики для тремора стрелок приборов
   ["EngineRPM"]       = 0,
   ["GMPPress F"]      = 0,
   ["WaterTemp F"]      = 0,
   ["OilPress F"]      = 0,
   ["GMPPress R"]      = 0,
   ["WaterTemp R"]      = 0,
   ["OilPress R"]      = 0,
   ["Speedometer F"]    = 0,
   ["Speedometer R"]    = 0}

-- В этом блоке ПЕРЕЧИСЛИТЬ ОБЯЗАТЕЛЬНО имена всех контролов в указанном формате, которые будут обновляться функцией UpdateControlWithTremor . Это счетчики колебаний синусоиды.
[...]
-- нужны для предотвращения сбоя фазы колебаний и защиты от переполнения переменной. Если кто-то найдет способ этот блок не использовать (см. код функции), это будет здорово.
Код: Выделить всё
if (TremorCounter [name] > 10) then -- защита от переполнения переменной-счетчика.
   TremorCounter [name] = 0;
end


Skif, опыт показал, что если стрелки должны "дрожать" в одной фазе, то можно обойтись всего лишь одной переменной-счетчиком, так как все значения таблицы имеют одно и то же значение.
По поводу переполнения этой переменной - лучше всего использовать как максимальное значение не 10, а 6.28, т.е. количество входящих в круг радианов - тогда синусоида будет идеальной, иначе она ломается при каждом обнулении. Число 6.28 - самый лучший вариант, так как меньшее значение не даст полную амплитуду колебаний, а большее - вызовет "наложение".

Если же использовать таблицу, можно автоматизировать её создание, чтобы не приходилось в обязательном порядке вписывать в неё все используемые контролы.
Для этого инкрементирование значений таблицы можно дополнить контролем существования полей для обрабатываемого контрола и создавать их сразу автоматически при необходимости:
Код: Выделить всё
   local n_inc = 1.0
   TremorCounter [name] = TremorCounter [name] and (TremorCounter [name] + n_inc*time) or 0

   if (TremorCounter [name] > 6.28) then -- защита от переполнения переменной-счетчика.
      TremorCounter [name] = 0
   end

Таким образом можно свести инициализацию таблицы лишь к её объявлению, все поля будут создаваться автоматически при первом вызове.
Единственный недостаток - возможная разная фаза в работе контролов. Если это критично, можно сделать синхронизацию.
В этом случае предыдущий блок выглядит так:
Код: Выделить всё
   local n_inc = 1.0
   TremorCounter [name] = TremorCounter [name] and (TremorCounter [name] + n_inc*time) or Synchronization()

   if (TremorCounter [name] > 6.28) then -- защита от переполнения переменной-счетчика.
      TremorCounter [name] = 0
   end
И дополнительно функция синхронизации:
Код: Выделить всё
function Synchronization()
   local value = 0
   for k, v in pairs(TremorCounter) do
      value = v
   end
   return value
end
Суть работы синхронизации сводится к тому, что вновь добавляемый счетчик контрола получает значение уже существующих в таблице. Если же таблица пустая (самый первый вход), то счетчик контрола получит значение 0.
Последний раз редактировалось Света 15.04.2017, 11:44, всего редактировалось 1 раз.
Забанена по собственному желанию. По важным вопросам связаться со мной можно через почту divovigna@gmail.com
Аватара пользователя
Света
 
Сообщения: 1338
Зарегистрирован: 18.06.2016, 19:38
Благодарил (а): 983 раз.
Поблагодарили: 1805 раз.
Играю в: Train Simulator Classic
Имя: Пандора

Re: LuaScript - для RS

Сообщение Skif » 15.04.2017, 11:31

Хм, спасибо, попробую. Возможно, в этом есть смысл.


Очень интересный код автогенерации таблицы, спасибо, Света. Не знал, что таблицы в LUA динамические!
Последний раз редактировалось Skif 16.04.2017, 11:14, всего редактировалось 1 раз.
Skif
 
Сообщения: 3750
Зарегистрирован: 01.10.2009, 17:42
Благодарил (а): 0 раз.
Поблагодарили: 2 раз.
Имя: Дмитрий

Re: LuaScript - для RS

Сообщение BooYa » 15.04.2017, 22:26

Прочитал. Сломал моск. :swoon:
Аватара пользователя
BooYa
 
Сообщения: 3748
Зарегистрирован: 24.01.2010, 16:30
Откуда: Екатеринбург
Благодарил (а): 1556 раз.
Поблагодарили: 2968 раз.
Играю в: Train Simulator Classic
Роль: Разработчик
Имя: Андрей

Re: LuaScript - для RS

Сообщение Linx » 15.04.2017, 23:00

А чего не понятного?

If TremorCounter brake Mosk and Mosk < 5 - защита от переполнения моска
Run function Drink (TremorCounter=true) to sinhronizationwithuorplanermotherearth
end
Дизайнер из Орла хочет познакомиться с бригадой ТЧ1 или ТЧ27. Маневры не предлагать :) | Простите, у вас кажется ригель отклеился!
Аватара пользователя
Linx
 
Сообщения: 1797
Зарегистрирован: 02.01.2006, 19:57
Откуда: Орел
Благодарил (а): 822 раз.
Поблагодарили: 1522 раз.
Блог: Просмотр блога (7)
Играю в: Train Simulator Classic
Роль: Разработчик
Имя: Дмитрий

Re: LuaScript - для RS

Сообщение BooYa » 16.04.2017, 05:45

:haha:
Аватара пользователя
BooYa
 
Сообщения: 3748
Зарегистрирован: 24.01.2010, 16:30
Откуда: Екатеринбург
Благодарил (а): 1556 раз.
Поблагодарили: 2968 раз.
Играю в: Train Simulator Classic
Роль: Разработчик
Имя: Андрей

Re: LuaScript - для RS

Сообщение Света » 22.04.2017, 13:42

Всем доброго дня :)

Требуется помощь по выведению формулы расчета скорости остывания двигателя. То есть, надо рассчитать, на сколько градусов цельсия снизится температура за секунду.
Из исходных данных - текущая температура, температура окружающей среды, время и коэффициент теплопередачи (0,05).
В сети удалось найти такую формулу:

t = –(1/k)•ln[(T2 – Tк) /(To – Tк) ]

где k - коэффициент теплопередачи, Т2 - конечная температура, То - текущая температура, Тк - температура окружающей среды.

Зная общее время, необходимое на полное остывание, и сколько времени прошло, я смогу, в принципе, определить, на сколько снизилась температура.
Но меня смущает громоздкость расчета. Да и нет уверенности в правильности формулы.
Кто-нибудь может помочь?
Реально ли обойтись этими исходными данными?
Спасибо.
Забанена по собственному желанию. По важным вопросам связаться со мной можно через почту divovigna@gmail.com
Аватара пользователя
Света
 
Сообщения: 1338
Зарегистрирован: 18.06.2016, 19:38
Благодарил (а): 983 раз.
Поблагодарили: 1805 раз.
Играю в: Train Simulator Classic
Имя: Пандора

Re: LuaScript - для RS

Сообщение Skif » 22.04.2017, 14:17

Привет, Света.


В моем тепловозе я исходил из упрощенной модели, при которой остывают жидкости по линейному закону до температуры окружающей среды. В настройках скрипта задана скорость остывания для воды и масла, а также среднесуточные температуры для четырех сезонов. Для зимы взята температура жидкостей выше нуля, так как у тепловоза не моделировался котел-подогреватель.

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

Если жидкости перегреваются выше заданных максимальных температур, термореле выбивает нагрузку и дизель будет работать на холостых оборотах, пока не остынет - блокируются цепи управления оборотами дизеля, снимается питание с вентилей регулятора.
Skif
 
Сообщения: 3750
Зарегистрирован: 01.10.2009, 17:42
Благодарил (а): 0 раз.
Поблагодарили: 2 раз.
Имя: Дмитрий

Re: LuaScript - для RS

Сообщение TRam_ » 22.04.2017, 19:15

Света писал(а):В сети удалось найти такую формулу:

это интегральная формула, для того чтоб вычислять время. А для моделирования надо наоборот, вычислять изменение температуры. Если эту формулу преобразовать и продифференцировать, получится банальное

dT = -k*(T-Tk) * dt

По ней и считай (т.е. фактически получится численное интегрирование). Чем меньше будет dt тем точнее, но я думаю для данной задачи можно даже с dt = 1 секунду использовать :) . Правда если k слишком большое, то решение может развалиться, и начнутся скачки, в этом случае нужно усложнять схему численного решения :) .
в z7 всё можно, а что нельзя - можно в sU
Аватара пользователя
TRam_
 
Сообщения: 1925
Зарегистрирован: 30.11.2007, 20:14
Благодарил (а): 2 раз.
Поблагодарили: 66 раз.
Играю в: Auran Trainz
Роль: Разработчик
Имя: Владимир

Re: LuaScript - для RS

Сообщение Skif » 22.04.2017, 21:43

И помни, что для тактирования нужно брать рассчитанную за предыдущую итерацию переменную времени, как сама советовала, Света.

Иначе, в лучших традициях от Dovetail Games, жидкости будут остывать пропорционально FPS сцены.
Skif
 
Сообщения: 3750
Зарегистрирован: 01.10.2009, 17:42
Благодарил (а): 0 раз.
Поблагодарили: 2 раз.
Имя: Дмитрий

Re: LuaScript - для RS

Сообщение i2GR » 23.04.2017, 01:22

http://railunion.net/blog/i2GR/ ЧС2-627 альфа, RSv07, АЛСН
Аватара пользователя
i2GR
 
Сообщения: 540
Зарегистрирован: 04.09.2008, 16:59
Благодарил (а): 260 раз.
Поблагодарили: 303 раз.
Блог: Просмотр блога (4)
Имя: Игорь

Re: LuaScript - для RS

Сообщение Света » 23.04.2017, 09:42

Skif, TRam_, спасибо за участие!
В общем, после повторного изучения школьного курса алгебры, у меня получилась такая динамика процесса остывания воды и масла:
Изображение
Так как опорные значения были сняты при температуре 60 градусов, графики перехлестнулись в этом месте.
Фактически, у меня получилось, что двигатель моего локомотива остыл от 60 до 21 градуса при температуре окружающей среды 20 градусов примерно за 2 часа.
Насколько это реалистично? (Опорные значения получены подсчетом скорости охлаждения воды и масла при заглушенном двигателе в ZD-simulator`е, но непонятно, для какой температуры окружающей среды это актуально :nenay:).

Добавлено спустя 41 минуту 23 секунды:
BooYa писал(а):Прочитал. Сломал моск. :swoon:

Я так понимаю, такую реакцию вызвала вот эта безобидная строчка:
"TremorCounter [name] = TremorCounter [name] and (TremorCounter [name] + n_inc*time) or 0"? :D

Дело в том, что lua позволяет делать такую конструкцию:
Код: Выделить всё
   переменная = условие and значение_если_условие == true or значение_если_условие == false
Это аналогично стандартному условию:
Код: Выделить всё
   if условие then
      переменная = значение_если_условие_true
   else
      переменная = значение_если_условие_false
   end

Результат одинаков, различие лишь в том, что первый вариант компактнее - 1 строка вместо 5 :up:
Соответственно, в строке выше в поле [имя_контрола] таблицы TremorCounter будет записано значение, которое там уже есть плюс n_inc*time, но только при условии, что TremorCounter [имя_контрола] == true, иначе, если TremorCounter [имя_контрола] == false, в это поле будет записан 0. А так как false будет только в двух случаях (если поля таблицы не существует вообще или если false ввести в таблицу напрямую), то ноль никогда не заменит корректное числовое значение.
Забанена по собственному желанию. По важным вопросам связаться со мной можно через почту divovigna@gmail.com
Аватара пользователя
Света
 
Сообщения: 1338
Зарегистрирован: 18.06.2016, 19:38
Благодарил (а): 983 раз.
Поблагодарили: 1805 раз.
Играю в: Train Simulator Classic
Имя: Пандора

Re: LuaScript - для RS

Сообщение Skif » 23.04.2017, 11:05

Выглядит достаточно круто - ты права, остывание идет по нелинейному закону в жизни. Поделись итоговым кодом рассчета остывания.


Я свой код писал, ориентируясь на тренажер, где не всегда есть время ждать, чтобы остыл тепловоз, если его перегрели (без перезапуска сценария, разумеется). Поэтому я намеренно ускорял процессы прогрева и охлаждения. На практике маломощный тепловоз вроде ТГМ-1 или ТУ7А греется от уличной температуры воды до рабочей 60 градусов от 15 мин до получаса на холостых оборотах, если включен термостат. У меня прогрев идет минуты три, что, разумеется, нереалистично, но удобно для игрока.
Skif
 
Сообщения: 3750
Зарегистрирован: 01.10.2009, 17:42
Благодарил (а): 0 раз.
Поблагодарили: 2 раз.
Имя: Дмитрий

Re: LuaScript - для RS

Сообщение Света » 23.04.2017, 15:17

Skif писал(а):Поделись итоговым кодом рассчета остывания.
Без проблем, отлажу и опубликую здесь.
Забанена по собственному желанию. По важным вопросам связаться со мной можно через почту divovigna@gmail.com
Аватара пользователя
Света
 
Сообщения: 1338
Зарегистрирован: 18.06.2016, 19:38
Благодарил (а): 983 раз.
Поблагодарили: 1805 раз.
Играю в: Train Simulator Classic
Имя: Пандора

Пред.След.

Вернуться в [RW] Другие вопросы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8