BarBoss 89 Опубликовано: 22 апреля, 2015 Итак пишем прогу, которая бесконечно гоняет робота взад-вперёд : 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() - тоже иногда пропускает. Что делать, как быть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
NEO 541 Опубликовано: 22 апреля, 2015 Используй gcc для отладки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Alex 4 683 Опубликовано: 22 апреля, 2015 Используй 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 перемещений! Вот робот стал кататься четко по меточкам, даже если вы встанете на пути или положите камешек, а потом уберете: До корректировки, да, он катался на случайное количество блоков, когда на 10, а иногда и на 3 или 4, потом разворачивался. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
FellHead 14 Опубликовано: 23 апреля, 2015 <p>Farlang - человек, который написал ферму с проверкой передвижений по координатам, лежит в готовых прогах</p> Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Farlang 13 Опубликовано: 23 апреля, 2015 (изменено) <p>Farlang - человек, который написал ферму с проверкой передвижений по координатам, лежит в готовых прогах</p> Там проверка движений очень тупая на самом деле, просто рекурсивным вызовом. Этот способ: local function forward() while not r.forward() do os.sleep(1) end os.sleep(0) end гораздо легче для выполнения, а еще количество попыток движения не ограничено. Надо бы фермера на него перенести как-нибудь. Изменено 23 апреля, 2015 пользователем Farlang Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
FellHead 14 Опубликовано: 23 апреля, 2015 Farlang сказал(а) 23 Апр 2015 - 07:54: Там проверка движений очень тупая на самом деле, просто рекурсивным вызовом Будь добр, кинь ссылку на код с умной проверкой) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
BarBoss Автор темы 89 Опубликовано: 23 апреля, 2015 Решение проблемы методом контроля исполнения команды передвижения, безусловно, рабочее. Но ведь робот не только движется. use() он тоже пропускает (хотя и много реже). Как её контролировать? А другие функции? Эдак мы придём к тому, что нужно весь API робота переписать. Что-то тут не то. Разработчик мода просто не мог такой проблемы не предусмотреть. Я играл на разных серверах с OC и на всех были лаги и фризы. Куда ж без них. Визуально робот застывал, а потом мгновенно перемещался на несколько позиций выполнив работу. Здесь же он застывает на месте, команды не исполняются. Такое впечатление, что сервер не успевает всё обработать, но вместо снижения TPS просто сбрасывает часть очереди, не обработав её. В их числе оказываются и "заявки" на действия роботов от виртуальных машин Lua. Для роботов такая рассинхронизация фатальна. Перемещение - это лишь часть проблем, то, что явно видно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Alex 4 683 Опубликовано: 23 апреля, 2015 Решение проблемы методом контроля исполнения команды передвижения, безусловно, рабочее. Но ведь робот не только движется. use() он тоже пропускает (хотя и много реже). Как её контролировать? А другие функции? Эдак мы придём к тому, что нужно весь API робота переписать. Что-то тут не то. Разработчик мода просто не мог такой проблемы не предусмотреть. Я играл на разных серверах с OC и на всех были лаги и фризы. Куда ж без них. Визуально робот застывал, а потом мгновенно перемещался на несколько позиций выполнив работу. Здесь же он застывает на месте, команды не исполняются. Такое впечатление, что сервер не успевает всё обработать, но вместо снижения TPS просто сбрасывает часть очереди, не обработав её. В их числе оказываются и "заявки" на действия роботов от виртуальных машин Lua. Для роботов такая рассинхронизация фатальна. Перемещение - это лишь часть проблем, то, что явно видно. Но факт. Я вчера был сам удивлен немного, что робот не выполняет, как положено 10 перемещений=) for i=1 , 10 do robot.forward() end Сам в шоке. Хоть и такими циклами редко пользовался. Проверь в сингле. Раньше, кстати никто не жаловался. Сервак уже 4 месяца маслает. Первый раз от тебя услышал, что у вас там на МТ такое, а теперь и на ИТ. По идее он дожен выполнить их!!! Но нет. Может как-то это связано с обновлением мода и прочее. Но раньше я не слухом не духом не слыхивал, что робот может проехать пять блоков вперед, копая под собой блоки и какой-то блок пропустить! Это нонсенс!!!!!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Totoro 3 563 Опубликовано: 23 апреля, 2015 Практически все команды робота возвращают true/false как индикатор успеха выполнения. Если вы вызываете еще один forward в то время, как робот еще предыдущий не завершил - не ждите, что он "включит нитро" и понесется быстрее. Проверяйте, и будет все хорошо. И организуйте ему слипы в цикле. Во время слипов обрабатываются эвенты и фоновые задачи. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Alex 4 683 Опубликовано: 23 апреля, 2015 Практически все команды робота возвращают true/false как индикатор успеха выполнения. Если вы вызываете еще один forward в то время, как робот еще предыдущий не завершил - не ждите, что он "включит нитро" и понесется быстрее. Проверяйте, и будет все хорошо. И организуйте ему слипы в цикле. Во время слипов обрабатываются эвенты и фоновые задачи. Во-во, про нитро-ускорители тоже была мысль Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
NEO 541 Опубликовано: 23 апреля, 2015 Черепашки рулят. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Alex 4 683 Опубликовано: 23 апреля, 2015 Черепашки рулят. Черепашки курят) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
BarBoss Автор темы 89 Опубликовано: 23 апреля, 2015 > Практически все команды робота возвращают true/false как индикатор успеха выполнения. Не всё так просто. Попытайтесь применить true/false для функции use() выполняемой над кропсом, растущим на жердочке, а я посмеюсь. Даже объехать на кривом козле с геолизером это нельзя - нет способа получить состояние кропса. Перемещение - это лишь самые примитивные и очевидные команды. Если вы вызываете еще один forward в то время, как робот еще предыдущий не завершил - не ждите, что он "включит нитро" и понесется быстрее. Проверяйте, и будет все хорошо. И организуйте ему слипы в цикле. Во время слипов обрабатываются эвенты и фоновые задачи. Этокакэто? У нас сервер в несколько потоков работает? И один поток пихает в очередь другого задачи асинхронно, не интересуясь выполнением предыдущей команды? Иначе описанное Вами "нитро" нереализуемо. А вот то, что я вполне допускаю - сервер при перегрузке сбрасывает с очереди обработки низкоприоритетные задачи - падение гравия, распространение воды, мобов и т.д. в это я готов поверить. И движение роботов попало туда-же. При том, что виртуальная машина lua осталась высокоприоритетной и добросовестно исполняется. Результат на лице. P.S. Это лишь мои домыслы. То, как я реализовал бы обработку будучи разработчиком серва. Реально работы сервера я не знаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Alex 4 683 Опубликовано: 23 апреля, 2015 Может есть смысл взять ванильный майн, дефолтный мод ОС и в одиночке потестить работу программы, которая в шапке темы? Тогда мы отметаем все серверные заморочки, рассинхроны, приоритеты, лаги, шмаги и прочее. Это многое должно прояснить. Возврат функции сразу на экран принтить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
BarBoss Автор темы 89 Опубликовано: 23 апреля, 2015 В одиночке нормально всё. Пробовал я. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Totoro 3 563 Опубликовано: 23 апреля, 2015 Не всё так просто. Попытайтесь применить true/false для функции use() выполняемой над кропсом, растущим на жердочке, а я посмеюсь. Даже объехать на кривом козле с геолизером это нельзя - нет способа получить состояние кропса. Перемещение - это лишь самые примитивные и очевидные команды. Этокакэто? У нас сервер в несколько потоков работает? И один поток пихает в очередь другого задачи асинхронно, не интересуясь выполнением предыдущей команды? Иначе описанное Вами "нитро" нереализуемо. А вот то, что я вполне допускаю - сервер при перегрузке сбрасывает с очереди обработки низкоприоритетные задачи - падение гравия, распространение воды, мобов и т.д. в это я готов поверить. И движение роботов попало туда-же. При том, что виртуальная машина lua осталась высокоприоритетной и добросовестно исполняется. Результат на лице. P.S. Это лишь мои домыслы. То, как я реализовал бы обработку будучи разработчиком серва. Реально работы сервера я не знаю. Функция use() возвращает true/false так же, как и остальные функции. В случае true добавляет описание произведенного действия. Под "робот пропускает действия" имеется ввиду, что робот возвращает "успех операции" не выполняя ее физически? По поводу мультипоточности я погорячился, да. Мне уже указали тут. Что, однако, не отменяет необходимости ставить слипы и делать проверки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
BarBoss Автор темы 89 Опубликовано: 23 апреля, 2015 (изменено) Функция use() возвращает true/false так же, как и остальные функции. В случае true добавляет описание произведенного действия. Под "робот пропускает действия" имеется ввиду, что робот возвращает "успех операции" не выполняя ее физически? По поводу мультипоточности я погорячился, да. Мне уже указали тут. Что, однако, не отменяет необходимости ставить слипы и делать проверки. Поэкспериментирую с кропсами завтра. Засада в том, что понятие "успех операции" весьма неоднозначно. false будет в двух случаях - если кропс не вырос и если действие пропущено. Как реагировать? Повторить? Игнорировать? Вангую такую ситуацию во многих случаях. Проверить состояние кропса нечем. Слипы в этой ситуации ничего принципиально не меняют. Я добавлял слипы в несколько секунд - эффекта вообще никакого. Если сервер сбросил запрос на обработку действия - ждать можно до морковкиного заговения. Проверять исполнена ли каждая команда - это нонсенс. Это нужно практически API робота переписать - не пихать же это счастье в каждую программу сызнова. Ведь робот не только двигается. А всякие апргрейды? Работа с жидкостями, инвентарём и прочее? Это же тихий ужас. И самое главное - раньше такой проблемы не было. ИМХО, тут в консерватории что-то не так. Изменено 23 апреля, 2015 пользователем BarBoss Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Totoro 3 563 Опубликовано: 23 апреля, 2015 Да, тоже раньше не слышал о такой проблеме. Рекурсивный майнер пахал сутками без сбоев. А там алгоритмы достаточно высокой точности требуют. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Alex 4 683 Опубликовано: 24 апреля, 2015 Да, тоже раньше не слышал о такой проблеме. Рекурсивный майнер пахал сутками без сбоев. А там алгоритмы достаточно высокой точности требуют. Вот именно! Там все работало, как часы, и нет там проверок на TRUE. Нужно безотлагательно создать экспертную комиссию и прозондировать этот вопрос более тщательно. Вплоть до петиции Сангару. Проверки раньше были в основном необходимы именно для убеждения, что робот дейсвительно продвинулся, и там нет преграды, блока. Но цикл for i=1 , 10 do robot.forward() end работал, если у робота нет ничего на пути, он 10 перемещений совершал, это к бабке не ходи А сейчас выходит так, что метод движения вызван, что-то он там вернул, и не дожидаясь физического перемещения робота он отдает управление программе дальше, а следующий вызов уже дает False, если робот не успел передвинуться. А может это фича, связанная с оптимизацией? Может так и должно быть, а мы ламеры и не знаем всей глубины глубин задумки Сангара?=) 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
cloud 248 Опубликовано: 14 мая, 2015 я тоже столкнулся с этой проблемой, но после долгих экспериментов и испытаний я отладил программу, теперь никаких пропусканий нет вообще. Как оказалось, метод 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, да и в программировании тоже, если ошибаюсь, скажите где. Но программа работает, проверено много раз, если надо скину исходники. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах