Перейти к содержимому
  • 0
vlad1vv1

Как прервать выполнение программы

Вопрос

Значит смысл темы такой: робот выполняет какую то программу, например фермы. Как прервать выполнение программы, не выключая робота(или компьютера), клавишей или вводом команды. Я хотел сделать с активной командной строкой, что бы ввести команду stop. Но что то не дошариваю, новичок я вообщем. Пробовал через term.read, прога вообще отказывается работать, вообщем запрос на ввод не получается. Где посмотреть, или поможете дописать?
https://pastebin.com/YmE4K22u
 

local robot = require("robot")
 
while true do
print("Введите [go] или [stop]")
  local a = io.read()
    if a == 'stop' then
      print("Программа остановлена")
      do return end
    else
      while true do
         if a == 'go' then    
          robot.forward()
          robot.turnLeft()
         else
          print("Введите задачу")
          do return end          
         end
      end
    end
end

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


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

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

Подскажите в чем я ошибся в своих измышизмах?

 

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

while true do
  if rs.getInput(sides.right) == 0 then
    print("Программа работает")
    robot.forward()
    os.sleep(1)
    robot.back()
    os.sleep(1)
  else
    print("Программа остановлена")
    break
  end
end

Мне надо что бы, например, если закончилась зарядка, робот прервал цикл, затем поехал заряжаться, после зарядки возобновил основной цикл

Это решается созданием виртуальной системы координат и нескольких функций, изменяющих значение x/y/z робота при его перемещении, учитывая поворот. Сдвинулся вперед? Прибавь единичку. Уровень заряда маловат? Вычисляй оптимальную траекторию для возвращения на базу, сохраняй текущие координаты, возвращайся и заряжайся, а затем уже иди обратно и продолжай работу. Нечто подобное я писал давненько, если интересно - можешь ознакомиться: https://github.com/IgorTimofeev/OpenComputers/blob/master/Applications/Robot/robotAPI.lua

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

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


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

Ctrl+ALt+C обычно помогает.

Это не комильфо)), интересно программно остановить. И у меня чет не работает Ctrl+ALt+C, когда робот двигается .

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

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


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

Это не комильфо)), интересно программно остановить.

Так обработка Ctrl+Alt+C и реализована программно, но средствами операционной системы.

Может быть, os.exit() комильфо?

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

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


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

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

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

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


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

Большинство программ, которые запущены под OpenOS, должны завершать работу поймав событие 'interrupt'.

 

Наверное, я ничего не забыл. К майнкрафту уже 2 месяца не притрагивался

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


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

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

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

Смысл может быть в получении опыта, например.

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


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

 

Очень странное это занятие -- искать смысл в игре майнкрафт. Лучше уж признаться себе, что смысл только воображаемый

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


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

Помню как поиграл в одиночном режиме и как-то вообще скучно стало. Без паблик сервера в кубаче совсем делать нечего

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


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

Очень странное это занятие -- искать смысл в игре майнкрафт. Лучше уж признаться себе, что смысл только воображаемый

Так и тема не о перекладывании кубиков, а о программировании. Так что, смысл вполне объективный.

 

А так это уже стало особой разновидностью местного спорта – рассказывать друг другу, насколько бессмысленна игра в Майнкрафт, как он уже всем надоел, и что программировать в Майнкрафте уже нечего, и всё уже написано.

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


Ссылка на сообщение
Поделиться на других сайтах
А так это уже стало особой разновидностью местного спорта – рассказывать друг другу, насколько бессмысленна игра в Майнкрафт, как он уже всем надоел, и что программировать в Майнкрафте уже нечего, и всё уже написано.

ничего еще не написано толком) нормальную агропрогу я  только припоминаю, это сборщик резины с поиском пути по потекам гевеи, от vx13.

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

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

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


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

ты посмотри на прогу в шапке. что тут можно обсуждать?

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

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


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

ничего еще не написано толком) нормальную агропрогу я  только припоминаю, это сборщик резины с поиском пути по потекам гевеи, от vx13.

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

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

Я не писал особо сложного, например, понимая принципы и используя копипаст, такие чудеса получаются, поэтому я не стал этого делать и мне просто хотелось понять суть. Конечно я понял про ивенты, это отслеживание событий по которым(ому) из них может быть выполнена команда, потому что я не совсем новичок. event.push('interrupt')  - про это еще не прочитал. Так вот задача какая, что бы помимо работающей проги, был активным ввод, куда можно ввести команду. И да в этот момент можно стопнуться, потому что будет прерывание цикла, ну что, ничего страшного.

P.S. Midnight Ccommander же не стопается, когда у него активный ввод, да?

 

Для чего это надо? Да просто так. Мозги расшевелить по lua, а с майном интереснее. У меня и сервера свои были и сейчас могу поднять. Средств не хватает. Мало того, действительно много здесь костылей)).

За что большое спасибо програмерам. Но все таки хочется что бы прога работала красиво, не только print("initialization..."). Кстати, прога, что предложенная работает на все 100, кроме ивентов конечно. Думаю у вас не так много новичков, которые пишут бесконечные цикл в цикле с условиями, которые корректно закачиваются. Если у вас есть возможность, еще что-то предложить буду только благодарен.

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

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


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

@@vlad1vv1 много способов есть. Нужно просто в твоем том главном цикле что-то проверять, или параллельно ловить какие-то ивенты.

Не думаю, что тебе будет удобно бежать за движущимся по змейке роботом, который что-то собирает,  и тыкать в его гуи и что-то там судорожно нажимать Ctrl+Alt+C, чтобы его стопнуть. Нужно или сетевое управление параллельное, или например ставить несколько точек с редстоуном (блок какой-то и рычаг ванильный) на местности его деятельности или парковки.

Робот едет себе по огороду и проверяет под брюхом в цикле на кажлом шаге наличие редсигнала. Как только увидел его, завис(слип) на 15 секунд, если сигнал есть, продолжил висеть 15 сек. Пересадил, что-то поменял на огороде, опустил рычаг, и робот дальше поехал. То есть типа питстопчик такой себе временный, и прочее прочее. Способов миллион. Что именно будет удобно тебе, не до конца понятно в теме, и как именно и для чего ты хочешь останавливать робота и зачем это нужно.

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


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

@@vlad1vv1 много способов есть. Нужно просто в твоем том главном цикле что-то проверять, или параллельно ловить какие-то ивенты.

Не думаю, что тебе будет удобно бежать за движущимся по змейке роботом, который что-то собирает,  и тыкать в его гуи и что-то там судорожно нажимать Ctrl+Alt+C, чтобы его стопнуть. Нужно или сетевое управление параллельное, или например ставить несколько точек с редстоуном (блок какой-то и рычаг ванильный) на местности его деятельности или парковки.

Робот едет себе по огороду и проверяет под брюхом в цикле на кажлом шаге наличие редсигнала. Как только увидел его, завис(слип) на 15 секунд, если сигнал есть, продолжил висеть 15 сек. Пересадил, что-то поменял на огороде, опустил рычаг, и робот дальше поехал. То есть типа питстопчик такой себе временный, и прочее прочее. Способов миллион. Что именно будет удобно тебе, не до конца понятно в теме, и как именно и для чего ты хочешь останавливать робота и зачем это нужно.

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

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

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


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

Заданный в ОП вопрос действительно интересен, поэтому я отвечу на него.

 

term.read, io.read, io.stdin:read — вот вся эта дружная команда не исполняется параллельно — понятно почему, я думаю. А если нужно?

 

Значит, или ввод, или выполнение действий таки надо заставить работать параллельно. Если два сделать, то получим демон, который захватит ввод, что достаточно глупо. Потому и варианта 2.

 

Вариант 1. Вынести ввод в параллель.

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

Мы можем переписать их так, чтобы они ловили ивенты листенерами, а не пуллом — получим собственную GUI-библиотеку.

Можно облегчить себе задачу, и использовать стороннюю GUI-библиотеку. Этот вариант предпочтительнее, если ещё нужно рисовать кого-то, помимо ввода.

 

А можно попробовать вынести ввод в тред. Треды — это такие штуки, которые были добавлены в одном из не столько давних обновлений OpenOS, и позволяют исполняться нескольким блокам кода параллельно — но не одновременно! Только что-то одно в данный момент времени, а переключение между тредами будет по os.sleep или event.pull.

 

Если у тебя в фермере после каждого вызова долгого метода (любое движение у робота таковым является) будет стоять хотя бы os.sleep(0), то можешь поставить такое:

local term = require("term")
local thread = require("thread")

thread.create(function()
  while true do
    local input = term.read()
    -- всё, дальше можем обрабатывать ввод
  end
end)

Есть у меня сомнения, что os.exit() из треда сработает, но можно попробовать. Сами треды чистить не нужно — они сами остановятся при завершении процесса.

 

Вариант 2. Параллельным делать обработку действий.

Этот вариант оптимальнее, говорю сразу.

 

Чтобы совсем ничего не менять, то можно просто обернуть саму обработку в отдельный тред, как в коде выше мы ввод принимали. Я бы так и сделал.

 

А можно зарегистрировать слушателей событий с помощью event.listen. Первым аргументом имя ивента, вторым — функция-обработчик.

Нельзя забывать поставить event.ignore в конце программы, иначе слушатель будет работать, как демон, вне процесса. Аргументы те же.

 

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

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


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

Заданный в ОП вопрос действительно интересен, поэтому я отвечу на него.

 

term.read, io.read, io.stdin:read — вот вся эта дружная команда не исполняется параллельно — понятно почему, я думаю. А если нужно?

 

Значит, или ввод, или выполнение действий таки надо заставить работать параллельно. Если два сделать, то получим демон, который захватит ввод, что достаточно глупо. Потому и варианта 2...

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

Спасибо. Буду пробовать. Как что получится отпишусь.

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

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


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

Вообщем пока я разбирался, стало ясно, робот не реагирует на ивенты мыши вообще, так устанавливается только монитор 1-го уровня.

Пока в цикле while true do выполняется движение робота, нельзя прервать ни ивентом любым, ни красным камнем. Пока цикл не начался, реагирует на все вообщем кроме мыши. На компьютере все ивенты работают для выхода из цикла. Т.е. для робота должна быть одна единая программа, если хочешь изменить алгоритм, останавливаешь одну программу, запускаешь другую. Кстати с тредами у меня получилось, задать поочередно движения робота, по оси Х отдельно, по оси Y отдельно. Получилось что-то вроде принтера.(Вперед-назад - один тред , шаг по оси Y другой тред.)
Подскажите в чем я ошибся в своих измышизмах? Мне надо что бы, например, если закончилась зарядка, робот прервал цикл, затем поехал заряжаться, после зарядки возобновил основной цикл.
 

---------------------------------------
--          Opencomputers            --            
---------------------------------------
-- Останов робота по красному камню  --
--        не работает                --
---------------------------------------
 
local robot = require("robot")
local component=require("component")
local sides=require("sides")
local rs=component.redstone
 
local c = true
 
while c do
print("Программа работает")
 
local b = rs.getInput(sides.right)
    if b > 0    then
      print("Программа остановлена")
      -- do return end
      c = false
     end
 
    if b == 0 then
      while true do
        robot.forward()
        os.sleep(1)
        robot.forward()
        os.sleep(1)
        robot.back()
        os.sleep(1)
        robot.back()
        os.sleep(1)
      end
    end
end
Изменено пользователем vlad1vv1

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


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

Подскажите в чем я ошибся в своих измышизмах? Мне надо что бы, например, если закончилась зарядка, робот прервал цикл, затем поехал заряжаться, после зарядки возобновил основной цикл.

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

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


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

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

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

Гость
Ответить на вопрос...

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

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

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

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

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


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