Перейти к содержимому
BarBoss

Робот пропускает движения.

Рекомендуемые сообщения

Итак пишем прогу, которая бесконечно гоняет робота взад-вперёд :

 

local r = require("robot")
local component = require("component")
local long = 10 -- длинна участка.
local pause = 5

-- гоняем робота взад - вперёд

repeat

 for bb=1 , long do
 r.forward()
 end
 r.turnAround()

 os.sleep(pause)

 

 for bb=1 , long do
 r.forward()
 end
 r.turnAround()

 

 os.sleep(pause)

until false

 

И убеждаемся, что робот рандомно пропускает движения.

И не только движения. use() - тоже иногда пропускает.

Что делать, как быть?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Используй gcc для отладки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Используй gcc для отладки.

 

Тут не в отладке дело. Что тут отлаживать? Три строки?

 

 

Итак пишем прогу, которая бесконечно гоняет робота взад-вперёд :

 

local r = require("robot")

local component = require("component")

local long = 10 -- длинна участка.

local pause = 5

-- гоняем робота взад - вперёд

repeat

for bb=1 , long do

r.forward()

end

r.turnAround()

os.sleep(pause)

 

for bb=1 , long do

r.forward()

end

r.turnAround()

 

os.sleep(pause)

until false

 

И убеждаемся, что робот рандомно пропускает движения.

И не только движения. use() - тоже иногда пропускает.

Что делать, как быть?

 

Да, действительно!

 

Просто цикл

for i=1 , 10 do 
   robot.forward()
end 

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

 

Во первых: No yield / sleep in the loop => нет гарантии правильной работы GC.

 

Во вторых:  сам метод robot.forward() то вызывается 10 раз, но так как он никак не проверяется и пытается выполнятся на огромной скорости, нет никакой гарантии, что он выполнился с TRUE. Проще говоря, может еще не наступить физическое перемещение робота, и следующий вызов метода выполняется с FALSE и перемещение пропускается. Так писать движение робота, видимо, нельзя!

 

Вот маленькая корректировка программы: 

local r = require("robot")
local component = require("component")

local long = 10 -- длинна участка.
local pause = 5

local function forward()
	while not r.forward() do
		os.sleep(1)
	end
        os.sleep(0)
end

-- гоняем робота взад - вперёд
while true do
	 for i=1 , long do 
	 	forward()
	 end 
	 	r.turnAround()
	 os.sleep(pause)
	 for i=1 , long do 
	 	forward()
	 end 
	 r.turnAround()
	 os.sleep(pause)
end

Здесь функция 

local function forward()
	while not r.forward() do
                --я написал паузу, но можете атаковать, разрушить блок и прочее, поставить любую задачу роботу
		os.sleep(1) 
	end
        os.sleep(0)
        --здесь можно увеличить координату и вернуть TRUE	
end

дождется выполнения перемещения, пока метод r.forward() не вернет TRUE. Робот переместится и цикл for пойдет дальше. Это гарантировано убережет нас от затыков сервера, маленьких подлагиваний и прочего. Иначе, вы не выполните четко 10 перемещений!

 

Вот робот стал кататься четко по меточкам, даже если вы встанете на пути или положите камешек, а потом уберете:

 

zRatW5u.png

 

До корректировки, да, он катался на случайное количество блоков, когда на 10, а иногда и на 3 или 4, потом разворачивался.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

<p>Farlang - человек, который написал ферму с проверкой передвижений по координатам, лежит в готовых прогах</p>

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

<p>Farlang - человек, который написал ферму с проверкой передвижений по координатам, лежит в готовых прогах</p>

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

Этот способ:

local function forward()
	while not r.forward() do
		os.sleep(1)
	end
        os.sleep(0)
end

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

Изменено пользователем Farlang

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Farlang сказал(а) 23 Апр 2015 - 07:54:

 

Там проверка движений очень тупая на самом деле, просто рекурсивным вызовом

Будь добр, кинь ссылку на код с умной проверкой)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Решение проблемы методом контроля исполнения команды передвижения, безусловно, рабочее. Но ведь робот не только движется. use() он тоже пропускает (хотя и много реже). Как её контролировать? А другие функции?  Эдак мы придём к тому, что нужно весь API робота переписать. Что-то тут не то. Разработчик мода просто не мог такой проблемы не предусмотреть.

Я играл на разных серверах с OC и на всех были лаги и фризы. Куда ж без них. Визуально робот застывал, а потом мгновенно перемещался на несколько позиций выполнив работу. Здесь же он застывает на месте, команды не исполняются. Такое впечатление, что сервер не успевает всё обработать, но вместо снижения TPS просто сбрасывает часть очереди, не обработав её. В их числе оказываются и "заявки" на действия роботов от виртуальных машин Lua. Для роботов такая рассинхронизация фатальна. Перемещение - это лишь часть проблем, то,  что явно видно.  :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Решение проблемы методом контроля исполнения команды передвижения, безусловно, рабочее. Но ведь робот не только движется. use() он тоже пропускает (хотя и много реже). Как её контролировать? А другие функции?  Эдак мы придём к тому, что нужно весь API робота переписать. Что-то тут не то. Разработчик мода просто не мог такой проблемы не предусмотреть.

Я играл на разных серверах с OC и на всех были лаги и фризы. Куда ж без них. Визуально робот застывал, а потом мгновенно перемещался на несколько позиций выполнив работу. Здесь же он застывает на месте, команды не исполняются. Такое впечатление, что сервер не успевает всё обработать, но вместо снижения TPS просто сбрасывает часть очереди, не обработав её. В их числе оказываются и "заявки" на действия роботов от виртуальных машин Lua. Для роботов такая рассинхронизация фатальна. Перемещение - это лишь часть проблем, то,  что явно видно.  :(

 

Но факт. Я вчера был сам удивлен немного, что робот не выполняет, как положено 10 перемещений=)

for i=1 , 10 do 
   robot.forward()
end 

Сам в шоке. Хоть и такими циклами редко пользовался. Проверь в сингле. Раньше, кстати никто не жаловался. Сервак уже 4 месяца маслает. Первый раз от тебя услышал, что у вас там на МТ такое, а теперь и на ИТ. По идее он дожен выполнить их!!! Но нет. Может как-то это связано с обновлением мода и прочее.

 

Но раньше я не слухом не духом не слыхивал, что робот может проехать пять блоков вперед, копая под собой блоки и какой-то блок пропустить! Это нонсенс!!!!!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Практически все команды робота возвращают true/false как индикатор успеха выполнения.

Если вы вызываете еще один forward в то время, как робот еще предыдущий не завершил - не ждите, что он "включит нитро" и понесется быстрее.

Проверяйте, и будет все хорошо. И организуйте ему слипы в цикле. Во время слипов обрабатываются эвенты и фоновые задачи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Практически все команды робота возвращают true/false как индикатор успеха выполнения.

Если вы вызываете еще один forward в то время, как робот еще предыдущий не завершил - не ждите, что он "включит нитро" и понесется быстрее.

Проверяйте, и будет все хорошо. И организуйте ему слипы в цикле. Во время слипов обрабатываются эвенты и фоновые задачи.

Во-во, про нитро-ускорители тоже была мысль  :D

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Черепашки рулят.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Черепашки рулят.

Черепашки курят)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

> Практически все команды робота возвращают true/false как индикатор успеха выполнения.

 

Не всё так просто. Попытайтесь применить true/false для функции use() выполняемой над кропсом, растущим на жердочке, а я посмеюсь. Даже объехать на кривом козле с геолизером это нельзя - нет способа получить состояние кропса.  Перемещение - это лишь самые примитивные и очевидные команды.

 

 

 

Если вы вызываете еще один forward в то время, как робот еще предыдущий не завершил - не ждите, что он "включит нитро" и понесется быстрее.

Проверяйте, и будет все хорошо. И организуйте ему слипы в цикле. Во время слипов обрабатываются эвенты и фоновые задачи.

 

Этокакэто? У нас сервер в несколько потоков работает? И один поток пихает в очередь другого задачи асинхронно,  не интересуясь выполнением предыдущей команды? Иначе описанное Вами "нитро" нереализуемо.

А вот то, что я вполне допускаю - сервер при перегрузке сбрасывает с очереди обработки низкоприоритетные задачи - падение гравия, распространение воды, мобов и т.д. в это я готов поверить. И движение роботов попало туда-же. При том, что виртуальная машина lua осталась высокоприоритетной и добросовестно исполняется. Результат на лице.

P.S. Это лишь мои домыслы. То, как я реализовал бы обработку будучи разработчиком серва. Реально работы сервера я не знаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Может есть смысл взять ванильный майн, дефолтный мод ОС и в одиночке потестить работу программы, которая в шапке темы?

Тогда мы отметаем все серверные заморочки, рассинхроны, приоритеты, лаги, шмаги и прочее. Это многое должно прояснить. Возврат функции сразу на экран принтить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

В одиночке нормально всё. Пробовал я.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Не всё так просто. Попытайтесь применить true/false для функции use() выполняемой над кропсом, растущим на жердочке, а я посмеюсь. Даже объехать на кривом козле с геолизером это нельзя - нет способа получить состояние кропса.  Перемещение - это лишь самые примитивные и очевидные команды.

 

Этокакэто? У нас сервер в несколько потоков работает? И один поток пихает в очередь другого задачи асинхронно,  не интересуясь выполнением предыдущей команды? Иначе описанное Вами "нитро" нереализуемо.

А вот то, что я вполне допускаю - сервер при перегрузке сбрасывает с очереди обработки низкоприоритетные задачи - падение гравия, распространение воды, мобов и т.д. в это я готов поверить. И движение роботов попало туда-же. При том, что виртуальная машина lua осталась высокоприоритетной и добросовестно исполняется. Результат на лице.

P.S. Это лишь мои домыслы. То, как я реализовал бы обработку будучи разработчиком серва. Реально работы сервера я не знаю.

 

Функция use() возвращает true/false так же, как и остальные функции. В случае true добавляет описание произведенного действия.

Под "робот пропускает действия" имеется ввиду, что робот возвращает "успех операции" не выполняя ее физически?

 

По поводу мультипоточности я погорячился, да. Мне уже указали тут. Что, однако, не отменяет необходимости ставить слипы и делать проверки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Функция use() возвращает true/false так же, как и остальные функции. В случае true добавляет описание произведенного действия.

Под "робот пропускает действия" имеется ввиду, что робот возвращает "успех операции" не выполняя ее физически?

 

По поводу мультипоточности я погорячился, да. Мне уже указали тут. Что, однако, не отменяет необходимости ставить слипы и делать проверки.

Поэкспериментирую с кропсами завтра. Засада в том, что понятие "успех операции" весьма неоднозначно. false будет в двух случаях - если кропс не вырос и если действие пропущено. Как реагировать? Повторить? Игнорировать? Вангую такую ситуацию во многих случаях. Проверить состояние кропса нечем.

 

Слипы в этой ситуации ничего принципиально не меняют. Я добавлял слипы в несколько секунд - эффекта вообще никакого. Если сервер сбросил запрос на обработку действия - ждать можно до морковкиного заговения. Проверять исполнена ли каждая команда - это нонсенс. Это нужно практически API робота переписать - не пихать же это счастье в каждую программу сызнова. Ведь робот не только двигается. А всякие апргрейды? Работа с жидкостями, инвентарём и прочее?  Это же тихий ужас. И самое главное - раньше такой проблемы не было. ИМХО, тут в консерватории что-то не так.

Изменено пользователем BarBoss

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да, тоже раньше не слышал о такой проблеме.

Рекурсивный майнер пахал сутками без сбоев. А там алгоритмы достаточно высокой точности требуют.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да, тоже раньше не слышал о такой проблеме.

Рекурсивный майнер пахал сутками без сбоев. А там алгоритмы достаточно высокой точности требуют.

 

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

 

Но цикл

for i=1 , 10 do 
   robot.forward()
end 

работал, если у робота нет ничего на пути, он 10 перемещений совершал, это к бабке не ходи :D

 

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

 

А может это фича, связанная с оптимизацией? Может так и должно быть, а мы ламеры и не знаем всей глубины глубин задумки Сангара?=)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

я тоже столкнулся с этой проблемой, но после долгих экспериментов и испытаний я отладил программу, теперь никаких пропусканий нет вообще. Как оказалось, метод robot.forward() никогда не возвращает false, если пройти не удалось он возвращает строку с причиной, и (как я думаю) она преобразуется в true. Вот фрагмент кода, который работает безотказно:

  function move(m)

    i = 1

    while i <= m do

      dig()

      if  robot.forward() == true then -- тут ==true ключевой момент, без него не работает корректно

        i = i + 1

      end

    end

  end

 

З.Ы. Я новичёк в LUA и в OC, да и в программировании тоже, если ошибаюсь, скажите где. Но программа работает, проверено много раз, если надо скину исходники.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

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

Гость
Ответить в тему...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...