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

Управление роботом через Terminal Glasses

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

Всем здравствуйте!

 

Авторы: xMikhailx, WildOne.

Вот решили попробовать свои силы, только начинаем, учимся, и не знаем, будет ли эта программа полезной для кого-нибудь, но надемся, что да, ведь пользователи - самая главная поддержка и помощь! Программа ещё далеко не готовая, и будет развиваться. Суть программы заключается в управлении роботом из ОС через очки (Terminal Glasses), на данный момент для реализации работы программы нужно достаточно много ресурсов, т.к. нужен сервер (компьютер) + робот (Tier 3) + Terminal Glasses Bridge + Terminal Glasses. Всё работает через связанную плату (Linked Card).

 

Команды для управления роботом (вводятся с очками в чат, начиная с $$):

 

 

Важно! Перед началом работы, в программе на роботе ввести число слотов инвентаря!
Сюда -> local inv = 48 (вместо 48)

 

$$clear - очищает интерфейс очков.

$$gf [количество блоков] - движение вперёд на указанное [количество блоков], если не указано, движение на один блок.
$$gfd [количество блоков] - аналогично предыдущему, но вскапывает блоки, встречающиеся на пути. (блок перед роботом и над роботом, чтобы человек мог пройти) 
$$gb [количество блоков] - движение назад на указанное [количество блоков], если не указано, движение на один блок.
$$tr - поворот направо на 90 градусов.
$$tl - поворот налево на 90 градусов.
$$ta - поворот на 180 градусов.
$$up [количество блоков] - подъем на указанное [количество блоков], если не указано, движение на один блок.
$$upd [количество блоков] - аналогично предыдущему, но вскапывает блоки, встречающиеся на пути.
$$dn [количество блоков] - спуск на указанное [количество блоков], если не указано, движение на один блок.
$$dnd [количество блоков] - аналогично предыдущему, но вскапывает блоки, встречающиеся на пути.
$$use - использовать предмет перед роботом (правая кнопка мыши).
$$useup - использовать предмет над роботом (правая кнопка мыши).
$$usedn - использовать предмет под роботом (правая кнопка мыши).
$$drop - выложить все вещи из инвентаря перед роботом (если перед роботом сундук, то в сундук).
$$dropup - выложить все вещи из инвентаря над роботом (если над роботом сундук, то в сундук).
$$dropdn - выложить все вещи из инвентаря под роботом (если под роботом сундук, то в сундук).
$$suck - забрать все вещи перед роботом (если перед роботом сундук, то из сундук).
$$suckup - забрать все вещи над роботом (если над роботом сундук, то из сундук).
$$suckdn - забрать все вещи под роботом (если под роботом сундук, то из сундук).

 

 

 

Схема такова:

1). Компьютер (Tier 3) - это и есть сервер. Применение: компьютер соединить с Terminal Glasses Bridge'мФункция: принимает команды от очков -> передаёт на робота команды -> принимает ответы от робота -> выводит ответы на очки.

Компоненты:

 

Связанная плата - обязательно, вся работа основана на ней!
Графическая карта (Tier 2)
Интернет карта (по желанию, нужна для скачивания программы)

Процессор (можно любой)
Оперативная память (много не нужно, тестировалось всё на 2-ух картах Tier 2)
Винчестер (любой)

 

 

2). Робот (Tier 3) - рабочая сила  :) Функция: принимает команды от сервера -> выполняет команды -> отправляет ответ на сервер.

Компоненты:

 

Связанная плата - обязательно, вся работа основана на ней!

Далее компоненты по желанию. 

 

 

 

Сами программы:

  1. Для сервера: http://pastebin.com/DB4va57x (для установки введите pastebin get DB4va57x server.lua)
    Код:

    local event = require("event")
    local t = require("component").tunnel
    local g = require("component").openperipheral_bridge
    
    --FUNCTIONS
    
    function AddMsgBox(_,_,_,_,_,msgbox)
    	g.clear()
    	g.addBox(1,1,200,10,0xFFFFFF,0.3)
    	g.addText(5,2,"Робот: "..msgbox,0xFF0000)
    	g.sync()
    end
    
    function clear()
    	g.clear()
    	g.sync()
    end
    
    function glasscommand(_,_,nick,_,gcom)
    	if gcom == "clear" then clear()
    	else
    		print(gcom)
    		t.send(gcom)
    	end
    end
    
    event.listen("glasses_chat_command",glasscommand)
    event.listen("modem_message",AddMsgBox)
    

  2. Для робота: http://pastebin.com/ZYNCQZx5 (для установки введите pastebin get ZYNCQZx5 control.lua)
    Код:


    local event = require("event")
    local r = require("robot")
    local t = require("component").tunnel
    local inv = 48                        --размер инвентаря робота
    
    --===================================--
    --         MOVEMENT FUNCTIONS        --
    --===================================--
    
    function gf()
    	local c = 1
    	if act[2]==nil then act[2]=1 end
    	for c = 1,act[2] do
    		r.forward()
    	end
    	t.send("Я сдвинулся на "..act[2].." блок(ов) вперёд")
    	print("Я сдвинулся на "..act[2].." блок(ов) вперёд")
    	c = 1
    end
    
    function gfd()
    	local dblocks = 0
    	if act[2]==nil then act[2]=1 end
    	for c = 1,act[2] do
    		repeat
    			if r.swing() then dblocks = dblocks+1 end
    			if r.swingUp() then dblocks = dblocks+1 end
    		until r.detect()==false or r.detectUp()==false
    		r.forward()
    		if r.swingUp() then dblocks = dblocks+1 end
    	end
    	t.send("Я сдвинулся на "..act[2].." блок(ов) вперёд и вскопал "..dblocks.." блок(ов)")
    	print("Я сдвинулся на "..act[2].." блок(ов) вперёд и вскопал "..dblocks.." блок(ов)")
    	c = 1
    end
    
    function gb()
    	local c = 1
    	if act[2]==nil then act[2]=1 end
    	for c = 1,act[2] do
    		r.back()
    	end
    	t.send("Я сдвинулся на "..act[2].." блок(ов) назад")
    	print("Я сдвинулся на "..act[2].." блок(ов) назад")
    	c = 1
    end
    
    function up()
    	local c = 1
    	if act[2]==nil then act[2]=1 end
    	for c = 1,act[2] do
    		r.up()
    	end
    	t.send("Я поднялся на "..act[2].." блок(ов)")
    	print("Я поднялся на "..act[2].." блок(ов)")
    	c = 1
    end
    
    function upd()
    	local dblocks = 0
    	local c = 1
    	if act[2]==nil then act[2]=1 end
    	for c = 1,act[2] do
    		repeat
    			if r.swingUp() then dblocks = dblocks+1 end
    		until r.detectUp()==false
    		r.up()
    		if r.swingUp() then dblocks = dblocks+1 end
    	end
    	t.send("Я поднялся на "..act[2].." блок(ов) и вскопал "..dblocks.." блок(ов)")
    	print("Я поднялся на "..act[2].." блок(ов) и вскопал "..dblocks.." блок(ов)")
    	c = 1
    end
    
    function dn()
    	local c = 1
    	if act[2]==nil then act[2]=1 end
    	for c = 1,act[2] do
    		r.down()
    	end
    	t.send("Я спустился на "..act[2].." блок(ов)")
    	print("Я спустился на "..act[2].." блок(ов)")
    	c = 1
    end
    
    function dnd()
    	local dblocks = 0
    	local c = 1
    	if act[2]==nil then act[2]=1 end
    	for c = 1,act[2] do
    		repeat
    			if r.swingDown() then dblocks = dblocks+1 end
    		until r.detectDown()==false
    		r.down()
    	end
    	t.send("Я спустился на "..act[2].." блок(ов) и вскопал "..dblocks.." блок(ов)")
    	print("Я спустился на "..act[2].." блок(ов) и вскопал "..dblocks.." блок(ов)")
    	c = 1
    end
    
    function tr()
    	r.turnRight()
    	t.send("Я повернулся направо")
    	print("Я повернулся направо")
    end
    
    function tl()
    	r.turnLeft()
    	t.send("Я повернулся налево")
    	print("Я повернулся налево")
    end
    
    function ta()
    	r.turnAround()
    	t.send("Я повернулся на 180 градусов")
    	print("Я повернулся на 180 градусов")
    end
    
    --===================================--
    --            USE FUNCTIONS          --
    --===================================--
    
    function use()
    	r.use()
    	t.send("Я щёлкнул правой мыши перед собой")
    	print("Я щёлкнул правой мыши перед собой")
    end
    
    function useup()
    	r.useUp()
    	t.send("Я щёлкнул правой мыши над собой")
    	print("Я щёлкнул правой мыши над собой")
    end
    
    function usedn()
    	r.useDown()
    	t.send("Я щёлкнул правой мыши под собой")
    	print("Я щёлкнул правой мыши под собой")
    end
    
    --===================================--
    --        INVENTORY FUNCTIONS        --
    --===================================--
    
    function drop()
    	for d=1,inv do
    		r.select(d)
    		r.drop(r.count())
    	end
    	r.select(1)
    	t.send("Я выбросил все вещи перед собой(или в сундук)")
    	print("Я выбросил все вещи перед собой(или в сундук)")
    end
    
    function dropup()
    	for d=1,inv do
    		r.select(d)
    		r.dropUp(r.count())
    	end
    	r.select(1)
    	t.send("Я выбросил все вещи над собой(или в сундук)")
    	print("Я выбросил все вещи над собой(или в сундук)")
    end
    
    function dropdn()
    	for d=1,inv do
    		r.select(d)
    		r.dropDown(r.count())
    	end
    	r.select(1)
    	t.send("Я выбросил все вещи под собой(или в сундук)")
    	print("Я выбросил все вещи под собой(или в сундук)")
    end
    
    function suck()
    	r.select(1)
    	while r.suck()==true do
    		r.suck()
    	end
    	t.send("Я забрал вещи перед собой(или из сундука)")
    	print("Я забрал вещи перед собой(или из сундука)")
    end
    
    function suckup()
    	r.select(1)
    	while r.suckUp()==true do
    		r.suckUp()
    	end
    	t.send("Я забрал вещи над собой(или из сундука)")
    	print("Я забрал вещи над собой(или из сундука)")
    end
    
    function suckdn()
    	r.select(1)
    	while r.suckDown()==true do
    		r.suckDown()
    	end
    	t.send("Я забрал вещи под собой(или из сундука)")
    	print("Я забрал вещи под собой(или из сундука)")
    end
    
    function error()
    	t.send("Ошибка. Неправильная команда")
    	print("Ошибка. Неправильная команда")
    end
    function obr(_,_,_,_,_,com,_)
    	local i = 1
    	act = {}
    	for word in string.gmatch(com, "%w+") do
    		--print(word)
    		act[i] = word
    		i = i + 1
    	end
    	print(act[1])
    	print(act[2])
    	if act[1] == "gf" then gf()
    	elseif act[1] == "gfd" then gfd()
    	elseif act[1] == "tr" then tr()
    	elseif act[1] == "tl" then tl()
    	elseif act[1] == "ta" then ta()
    	elseif act[1] == "up" then up()
    	elseif act[1] == "dn" then dn()
    	elseif act[1] == "upd" then upd()
    	elseif act[1] == "dnd" then dnd()
    	elseif act[1] == "gb" then gb()
    	elseif act[1] == "use" then use()
    	elseif act[1] == "useup" then useup()
    	elseif act[1] == "usedn" then usedn()
    	elseif act[1] == "drop" then drop()
    	elseif act[1] == "dropup" then dropup()
    	elseif act[1] == "dropdn" then dropdn()
    	elseif act[1] == "suck" then suck()
    	elseif act[1] == "suckup" then suckup()
    	elseif act[1] == "suckdn" then suckdn()
    	else error()
    end
    end
    
    event.listen("modem_message",obr)

На самом деле главное - то, что мы старались делая программу и получили опыт, мы этому очень рады!

Критика, поддержка, пожелания, предложения, VIP-статус - всё принимается!  :D

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

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


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

Да, конечно инвентаря, случайно описался) А что ты думаешь по поводу программы?

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

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


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

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

Размер инвентаря можно замерить циклом или вводить через очки.

 

А так, для начала, очень даже неплохо.

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


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

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

Размер инвентаря можно замерить циклом или вводить через очки.

 

А так, для начала, очень даже неплохо.

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

 

Да, про цикл думал, нужно сделать, согласен.

 

Спасибо  :)

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


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

Юзай мост от Леши и Монстра) Он круче связанной платы: можно между серверами передавать сообщения))

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


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

Не парьтесь с циклом, используйте robot.inventorySize() ;)

Только что тоже нашёл эту функцию, раньше смотрел на Gamepedi'и, а сейчас посмотрел в документации самого OpenComputers! Спасибо!

 

А что ты думаешь по поводу программы?  :)

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


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

Юзай мост от Леши и Монстра) Он круче связанной платы: можно между серверами передавать сообщения))

Что-то не смог найти этот мост, кинь ссылку)

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


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

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

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

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


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

Последовательности из большого количества elseif можно заменять на таблицу функций. Сравни эти две реализации:

if     a==1 then foo1()
elseif a==2 then foo2()
elseif a==3 then foo3()
elseif a==4 then foo4()
elseif a==5 then foo5()
-- и т.д.
else error()
end

и

t={foo1,foo2,foo3,foo4,foo5 }
if t[a] then t[a]()
else error()
end

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


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

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

Должна повыситься, исходный код OC по этому поводу не смотрел, но мне кажется, там нет ограничителя)

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


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

 

Последовательности из большого количества elseif можно заменять на таблицу функций. Сравни эти две реализации:

if     a==1 then foo1()
elseif a==2 then foo2()
elseif a==3 then foo3()
elseif a==4 then foo4()
elseif a==5 then foo5()
-- и т.д.
else error()
end

и

t={foo1,foo2,foo3,foo4,foo5 }
if t[a] then t[a]()
else error()
end

Приму к сведению, исправлю, спасибо)

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


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

исходный код OC по этому поводу не смотрел

Смотри: https://github.com/MightyPirates/OpenComputers/blob/master-MC1.7.10/src/main/scala/li/cil/oc/server/component/InternetCard.scala

Если не учитывать время на обработку запроса самим модом, то всё упирается в скорость инет-соединения между запрашиваемым ресурсом и, собственно, самим хостом. В условиях отсутствия интернета (кратковременного или продолжительного) польза от инет-карты магическим образом пропадает, если только не включить запросы на локалхост в конфигах и затем уже посылать туда требования. Как мне кажется, программы не должны выходить за границы выполняемой среды, в данном случае — игры, делая исключения, когда это действительно необходимо, но не в этом случае. Особенно пугает возможная зависимость от какого-то левого хоста. Где гарантия, что софт там не будет совершать нежелательные действия, типа хранения передаваемых данных?

 

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

 

В конце концов слабо́ систему сделать полностью внутриигровой, без использования сторонних и сомнительных средств? ;) B-)

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


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

Смотри: https://github.com/MightyPirates/OpenComputers/blob/master-MC1.7.10/src/main/scala/li/cil/oc/server/component/InternetCard.scala

Если не учитывать время на обработку запроса самим модом, то всё упирается в скорость инет-соединения между запрашиваемым ресурсом и, собственно, самим хостом. В условиях отсутствия интернета (кратковременного или продолжительного) польза от инет-карты магическим образом пропадает, если только не включить запросы на локалхост в конфигах и затем уже посылать туда требования. Как мне кажется, программы не должны выходить за границы выполняемой среды, в данном случае — игры, делая исключения, когда это действительно необходимо, но не в этом случае. Особенно пугает возможная зависимость от какого-то левого хоста. Где гарантия, что софт там не будет совершать нежелательные действия, типа хранения передаваемых данных?

 

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

 

В конце концов слабо́ систему сделать полностью внутриигровой, без использования сторонних и сомнительных средств? ;) B-)

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

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


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

Что мешает юзать вай-файки? Добавить роботу в переменные имя и пароль. Кто то (А) броадкастит "ЭТО ТЫ supername228?", робот (Б) отвечает send'ом "ДА ЭТО Я, ГОНИ ПАРОЛЬ", комп (А) отвечает send'ом "ВОТ: superpass100500" (Б) сендит поттверждение, после этого они обмениваются информацией сендами. (До этого записав адреса которые они получили от Эвента)

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


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

Что мешает юзать вай-файки? Добавить роботу в переменные имя и пароль. Кто то (А) броадкастит "ЭТО ТЫ supername228?", робот (Б) отвечает send'ом "ДА ЭТО Я, ГОНИ ПАРОЛЬ", комп (А) отвечает send'ом "ВОТ: superpass100500" (Б) сендит поттверждение, после этого они обмениваются информацией сендами. (До этого записав адреса которые они получили от Эвента)

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

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


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

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

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

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

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

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

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

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

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


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