Advertisement
Ewgeniy

robot_ai

May 6th, 2025 (edited)
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.27 KB | None | 0 0
  1. -- Автономный ИИ-Контроллер Робота для OpenComputers с логированием ошибок в файл
  2.  
  3. local component   = require("component")
  4. local robot       = require("robot")
  5. local computer    = require("computer")
  6. local internet    = require("internet")
  7. local json        = require("json")
  8. local tty         = require("tty")
  9.  
  10. -- Инициализация компонентов
  11. local nav         = component.navigation
  12. local radar       = component.isAvailable("radar") and component.radar or nil
  13. local chat        = component.isAvailable("chat") and component.chat or nil
  14. local camera_comp = component.isAvailable("camera") and component.camera or nil
  15. local radar       = component.isAvailable("radar") and component.radar or nil
  16. local chat        = component.isAvailable("chat") and component.chat or nil
  17. local camera_comp = component.isAvailable("camera") and component.camera or nil
  18.  
  19. -- Настройка консоли
  20. tty.clear()
  21. print("=== Автономный ИИ-Контроллер Робота ===")
  22. io.write("Введите API-ключ Mistral: ")
  23. local api_key = io.read()
  24.  
  25. -- Константы API
  26. local MISTRAL_URL   = "https://api.mistral.ai/v1/chat/completions"
  27. local TRANSLATE_URL = "https://translate.googleapis.com/translate_a/single"
  28.  
  29. -- Путь для логов ошибок
  30. local ERROR_LOG = "/robot_errors.log"
  31.  
  32. -- Функция для записи ошибки в файл
  33. local function log_error(err)
  34.   local file = io.open(ERROR_LOG, "a")
  35.   if file then
  36.     file:write(os.date("%Y-%m-%d %H:%M:%S"), " - ERROR: ", err, "\n")
  37.     file:close()
  38.   end
  39. end
  40.  
  41. -- HTTP-заголовки для Mistral
  42. local headers = {
  43.   ["Authorization"] = "Bearer " .. api_key,
  44.   ["Content-Type"]  = "application/json"
  45. }
  46.  
  47. -- URL-энкодинг для translate
  48. local function urlencode(str)
  49.   if not str then return "" end
  50.   str = str:gsub("\n", "\r\n")
  51.   str = str:gsub("([^%w ])", function(c) return string.format("%%%02X", string.byte(c)) end)
  52.   return str:gsub(" ", "+")
  53. end
  54.  
  55. -- Перевод текста через Google Translate
  56. local function translate(text, lang)
  57.   local url = TRANSLATE_URL .. "?client=gtx&sl=auto&tl=" .. lang .. "&dt=t&q=" .. urlencode(text)
  58.   local ok, res = pcall(internet.request, url)
  59.   if not ok or not res then return text end
  60.   local body = "" for chunk in res do body = body .. chunk end
  61.   local success, dec = pcall(json.decode, body)
  62.   if not success or not dec or not dec[1] then return text end
  63.   local out = "" for _, seg in ipairs(dec[1]) do out = out .. (seg[1] or "") end
  64.   return out
  65. end
  66.  
  67. -- Системное сообщение ИИ
  68. local messages = {
  69.   { role = "system", content = [[
  70. You are an AI robot controller. Every 5 seconds respond with a JSON array of command objects
  71. for the robot to execute next.
  72. Example:
  73. [
  74.   {"action":"move","direction":"forward"}
  75. ]
  76. Always output ONLY this JSON array without any additional text.]] }
  77. }
  78.  
  79. -- Запрос следующего плана у ИИ
  80. local function plan_next(state)
  81.   table.insert(messages, { role = "user", content = translate(json.encode(state), "en") })
  82.   local payload = { model = "mistral-large-latest", messages = messages }
  83.   local ok_req, resp = pcall(internet.request, MISTRAL_URL, json.encode(payload), headers)
  84.   if not ok_req or not resp then error("Connection error to AI API") end
  85.   local raw = "" for chunk in resp do raw = raw .. chunk end
  86.   local ok_dec, dec = pcall(json.decode, raw)
  87.   if not ok_dec or not dec or not dec.choices then error("Invalid AI response: " .. raw) end
  88.   local reply = dec.choices[1].message.content
  89.   table.insert(messages, { role = "assistant", content = reply })
  90.   local ok_json, cmds = pcall(json.decode, reply)
  91.   if not ok_json then error("Failed parsing commands: " .. reply) end
  92.   return cmds
  93. end
  94.  
  95. -- Мысли ИИ: публикуем в чат
  96. local function think_and_say(commands)
  97.   local thought = "Thinking to execute: " .. json.encode(commands)
  98.   if chat then chat.say(translate(thought, "ru")) end
  99. end
  100.  
  101. -- Исполнение команд на роботе
  102. local function execute(commands)
  103.   for _, cmd in ipairs(commands) do
  104.     if cmd.action == "move" then
  105.       if cmd.direction == "forward" then
  106.         if not robot.forward() then robot.swing() robot.forward() end
  107.       elseif cmd.direction == "back" then
  108.         robot.back()
  109.       elseif cmd.direction == "up" then
  110.         if not robot.up() then robot.swingUp() robot.up() end
  111.       elseif cmd.direction == "down" then
  112.         if not robot.down() then robot.swingDown() robot.down() end
  113.       end
  114.     elseif cmd.action == "turn" then
  115.       if cmd.direction == "left" then
  116.         robot.turnLeft()
  117.       elseif cmd.direction == "right" then
  118.         robot.turnRight()
  119.       end
  120.     elseif cmd.action == "moveTo" then
  121.       nav.goTo(cmd.x or 0, cmd.y or 0, cmd.z or 0)
  122.     elseif cmd.action == "scan" and radar then
  123.       radar.getEntities()
  124.     elseif cmd.action == "distance" and camera_comp then
  125.       camera_comp.distance(cmd.x or 0, cmd.y or 0)
  126.     elseif cmd.action == "distanceUp" and camera_comp then
  127.       camera_comp.distanceUp(cmd.x or 0, cmd.y or 0)
  128.     elseif cmd.action == "distanceDown" and camera_comp then
  129.       camera_comp.distanceDown(cmd.x or 0, cmd.y or 0)
  130.     elseif cmd.action == "say" and chat then
  131.       chat.say(cmd.message or "")
  132.     elseif cmd.action == "shutdown" then
  133.       computer.shutdown()
  134.     end
  135.   end
  136. end
  137.  
  138. -- Основной автономный цикл
  139. while true do
  140.   local pos = { nav.getPosition() }
  141.   local state = {
  142.     energy   = computer.energy(),
  143.     position = { x = pos[1], y = pos[2], z = pos[3] },
  144.     facing   = nav.getFacing(),
  145.     radar    = radar and #radar.getEntities() or 0,
  146.     front    = camera_comp and camera_comp.distance() or nil,
  147.     up       = camera_comp and camera_comp.distanceUp() or nil,
  148.     down     = camera_comp and camera_comp.distanceDown() or nil
  149.   }
  150.  
  151.   local ok_plan, commands_or_err = pcall(plan_next, state)
  152.   if not ok_plan then
  153.     log_error("Plan error: " .. tostring(commands_or_err))
  154.   else
  155.     think_and_say(commands_or_err)
  156.     local ok_exec, exec_err = pcall(execute, commands_or_err)
  157.     if not ok_exec then log_error("Execute error: " .. tostring(exec_err)) end
  158.   end
  159.  
  160.   os.sleep(5)
  161. end
  162.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement