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


Фотография

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


Лучший Ответ ECS , 05 Март 2018 - 21:57

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

 
В указанном примере робот проверяет отсутствие редстоун-сигнала, а затем, убедившись в этом, входит в бесконечный цикл на 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/I...ot/robotAPI.lua Перейти к сообщению


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 22

#1 Оффлайн   vlad1vv1

vlad1vv1
  • Пользователи
  • Сообщений: 22
  • Уровень сигнала: 3,73%
  • В игре: 32 час. 4 мин.

Отправлено 28 Февраль 2018 - 19:54

Значит смысл темы такой: робот выполняет какую то программу, например фермы. Как прервать выполнение программы, не выключая робота(или компьютера), клавишей или вводом команды. Я хотел сделать с активной командной строкой, что бы ввести команду 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


#2 Онлайн   eu_tomat

eu_tomat
  • Хранители Кода
  • Сообщений: 936
  • Уровень сигнала: 5,93%
  • В игре: 50 час. 55 мин.

Награды

                          

Отправлено 28 Февраль 2018 - 19:57

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

#3 Оффлайн   vlad1vv1

vlad1vv1
  • Автор темы
  • Пользователи
  • Сообщений: 22
  • Уровень сигнала: 3,73%
  • В игре: 32 час. 4 мин.

Отправлено 28 Февраль 2018 - 19:58

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

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


Сообщение отредактировал vlad1vv1: 28 Февраль 2018 - 20:49

  • Quant это нравится

#4 Онлайн   eu_tomat

eu_tomat
  • Хранители Кода
  • Сообщений: 936
  • Уровень сигнала: 5,93%
  • В игре: 50 час. 55 мин.

Награды

                          

Отправлено 28 Февраль 2018 - 20:05

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

Так обработка Ctrl+Alt+C и реализована программно, но средствами операционной системы.
Может быть, os.exit() комильфо?

Сообщение отредактировал eu_tomat: 28 Февраль 2018 - 20:07


#5 Оффлайн   RccHD

RccHD
  • Пользователи
  • Сообщений: 169
  • Уровень сигнала: 15,1%
  • В игре: 129 час. 42 мин.

Награды

           

Отправлено 28 Февраль 2018 - 20:45

event.push('interrupt')

#6 Оффлайн   Alex

Alex
  • Администраторы
  • Сообщений: 3 787
  • Уровень сигнала: 46,36%
  • В игре: 398 час. 9 мин.

Награды

                 

Отправлено 28 Февраль 2018 - 20:46

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

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


  • davial это нравится

#7 Оффлайн   RccHD

RccHD
  • Пользователи
  • Сообщений: 169
  • Уровень сигнала: 15,1%
  • В игре: 129 час. 42 мин.

Награды

           

Отправлено 28 Февраль 2018 - 21:04

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

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

#8 Онлайн   eu_tomat

eu_tomat
  • Хранители Кода
  • Сообщений: 936
  • Уровень сигнала: 5,93%
  • В игре: 50 час. 55 мин.

Награды

                          

Отправлено 28 Февраль 2018 - 21:08

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

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

#9 Оффлайн   RccHD

RccHD
  • Пользователи
  • Сообщений: 169
  • Уровень сигнала: 15,1%
  • В игре: 129 час. 42 мин.

Награды

           

Отправлено 28 Февраль 2018 - 21:22

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



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

#10 Оффлайн   RccHD

RccHD
  • Пользователи
  • Сообщений: 169
  • Уровень сигнала: 15,1%
  • В игре: 129 час. 42 мин.

Награды

           

Отправлено 28 Февраль 2018 - 21:25

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

#11 Онлайн   eu_tomat

eu_tomat
  • Хранители Кода
  • Сообщений: 936
  • Уровень сигнала: 5,93%
  • В игре: 50 час. 55 мин.

Награды

                          

Отправлено 28 Февраль 2018 - 21:34

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

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

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

#12 Оффлайн   Alex

Alex
  • Администраторы
  • Сообщений: 3 787
  • Уровень сигнала: 46,36%
  • В игре: 398 час. 9 мин.

Награды

                 

Отправлено 28 Февраль 2018 - 23:45

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

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

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

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



#13 Онлайн   eu_tomat

eu_tomat
  • Хранители Кода
  • Сообщений: 936
  • Уровень сигнала: 5,93%
  • В игре: 50 час. 55 мин.

Награды

                          

Отправлено 28 Февраль 2018 - 23:55

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

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

#14 Оффлайн   vlad1vv1

vlad1vv1
  • Автор темы
  • Пользователи
  • Сообщений: 22
  • Уровень сигнала: 3,73%
  • В игре: 32 час. 4 мин.

Отправлено 01 Март 2018 - 01:15

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

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

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

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

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


Сообщение отредактировал vlad1vv1: 01 Март 2018 - 01:45


#15 Оффлайн   Alex

Alex
  • Администраторы
  • Сообщений: 3 787
  • Уровень сигнала: 46,36%
  • В игре: 398 час. 9 мин.

Награды

                 

Отправлено 01 Март 2018 - 02:20

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

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

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



#16 Оффлайн   vlad1vv1

vlad1vv1
  • Автор темы
  • Пользователи
  • Сообщений: 22
  • Уровень сигнала: 3,73%
  • В игре: 32 час. 4 мин.

Отправлено 01 Март 2018 - 10:52

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

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

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

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


Сообщение отредактировал vlad1vv1: 01 Март 2018 - 11:05


#17 Оффлайн   Fingercomp

Fingercomp
  • Гуру
  • Сообщений: 2 015
  • Уровень сигнала: 149%
  • В игре: 1279 час. 35 мин.

Награды

                                               

Отправлено 01 Март 2018 - 11:02

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

 

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 в конце программы, иначе слушатель будет работать, как демон, вне процесса. Аргументы те же.

 

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


  • eu_tomat и vlad1vv1 это нравится

#18 Оффлайн   vlad1vv1

vlad1vv1
  • Автор темы
  • Пользователи
  • Сообщений: 22
  • Уровень сигнала: 3,73%
  • В игре: 32 час. 4 мин.

Отправлено 01 Март 2018 - 18:06

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

 

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

 

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

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

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


Сообщение отредактировал vlad1vv1: 01 Март 2018 - 18:07


#19 Оффлайн   vlad1vv1

vlad1vv1
  • Автор темы
  • Пользователи
  • Сообщений: 22
  • Уровень сигнала: 3,73%
  • В игре: 32 час. 4 мин.

Отправлено 05 Март 2018 - 18:26

Вообщем пока я разбирался, стало ясно, робот не реагирует на ивенты мыши вообще, так устанавливается только монитор 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: 05 Март 2018 - 18:39


#20 Оффлайн   ECS

ECS
  • Гуру
  • Сообщений: 204
  • Уровень сигнала: 0,49%
  • В игре: 4 час. 10 мин.
  • ГородСанкт-Петербург

Награды

   10                  

Отправлено 05 Март 2018 - 21:57   Лучший Ответ

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

 
В указанном примере робот проверяет отсутствие редстоун-сигнала, а затем, убедившись в этом, входит в бесконечный цикл на 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/I...ot/robotAPI.lua

Сообщение отредактировал ECS: 05 Март 2018 - 22:02

  • eu_tomat и vlad1vv1 это нравится

#21 С мобильного устройства Онлайн   NEO

NEO
  • Пользователи
  • Сообщений: 1 780
  • Уровень сигнала: 4,24%
  • В игре: 36 час. 25 мин.
  • ГородСолнце

Награды

   3                        

Отправлено 05 Март 2018 - 23:10

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

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


  • Doob и vlad1vv1 это нравится

#22 Оффлайн   vlad1vv1

vlad1vv1
  • Автор темы
  • Пользователи
  • Сообщений: 22
  • Уровень сигнала: 3,73%
  • В игре: 32 час. 4 мин.

Отправлено 07 Март 2018 - 14:35

 
В указанном примере робот проверяет отсутствие редстоун-сигнала, а затем, убедившись в этом, входит в бесконечный цикл на 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/I...ot/robotAPI.lua

 

 

"Чем больше циклов - тем больше жепы" - Да именно так и получается). Вообщем пришел я к такому выводу что вот этот вариант оптимальный: "Просто вставляешь вызов функции в основной цикл которая занимается возвратом"

И получается пример общий для робота, который работает. Основная программа делается в бесконечным цикле, а переходы осуществляются между функциями с конечным циклом. Так у меня все заработало. 

=====================================
= Программа перехода от действия    =
= к действию для робота             =
=====================================
-- подключение API
-- подключение компонентов
-- объявление переменных

function Line_1() - например сажаем пшеницу

  for i = 1, 10 do - цикл обязательно должен быть конечным
  --- тело цикла

  end
end

или 

function Line_2() -- собираем пшеницу

  repeat     -- также цикл должен быть конечным
  i = i + 1
  ---
  --- блок команд

  until - проверка на не только <,>,==, >=, но и на true и false

end

-- Далее, что бы все делалось автоматически (основная программа)

while true do

Line_1()

if условие then Line_2() - инструкции могут быть как с условием, так и просто последовательные.
end

end

Сообщение отредактировал vlad1vv1: 07 Март 2018 - 14:38


#23 Оффлайн   mrlobaker

mrlobaker
  • Пользователи
  • Сообщений: 10
  • Уровень сигнала: 0,11%
  • В игре: 0 час. 57 мин.

Отправлено 26 Март 2018 - 13:20

Так проблема в том, что если программа не получает stop, то ждёт только go из-за лишнего while на 10 строчке. Никто этого не увидел?






Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных