Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Автономный ИИ-Контроллер Робота для OpenComputers с логированием ошибок в файл
- local component = require("component")
- local robot = require("robot")
- local computer = require("computer")
- local internet = require("internet")
- local json = require("json")
- local tty = require("tty")
- -- Инициализация компонентов
- local nav = component.navigation
- local radar = component.isAvailable("radar") and component.radar or nil
- local chat = component.isAvailable("chat") and component.chat or nil
- local camera_comp = component.isAvailable("camera") and component.camera or nil
- local radar = component.isAvailable("radar") and component.radar or nil
- local chat = component.isAvailable("chat") and component.chat or nil
- local camera_comp = component.isAvailable("camera") and component.camera or nil
- -- Настройка консоли
- tty.clear()
- print("=== Автономный ИИ-Контроллер Робота ===")
- io.write("Введите API-ключ Mistral: ")
- local api_key = io.read()
- -- Константы API
- local MISTRAL_URL = "https://api.mistral.ai/v1/chat/completions"
- local TRANSLATE_URL = "https://translate.googleapis.com/translate_a/single"
- -- Путь для логов ошибок
- local ERROR_LOG = "/robot_errors.log"
- -- Функция для записи ошибки в файл
- local function log_error(err)
- local file = io.open(ERROR_LOG, "a")
- if file then
- file:write(os.date("%Y-%m-%d %H:%M:%S"), " - ERROR: ", err, "\n")
- file:close()
- end
- end
- -- HTTP-заголовки для Mistral
- local headers = {
- ["Authorization"] = "Bearer " .. api_key,
- ["Content-Type"] = "application/json"
- }
- -- URL-энкодинг для translate
- local function urlencode(str)
- if not str then return "" end
- str = str:gsub("\n", "\r\n")
- str = str:gsub("([^%w ])", function(c) return string.format("%%%02X", string.byte(c)) end)
- return str:gsub(" ", "+")
- end
- -- Перевод текста через Google Translate
- local function translate(text, lang)
- local url = TRANSLATE_URL .. "?client=gtx&sl=auto&tl=" .. lang .. "&dt=t&q=" .. urlencode(text)
- local ok, res = pcall(internet.request, url)
- if not ok or not res then return text end
- local body = "" for chunk in res do body = body .. chunk end
- local success, dec = pcall(json.decode, body)
- if not success or not dec or not dec[1] then return text end
- local out = "" for _, seg in ipairs(dec[1]) do out = out .. (seg[1] or "") end
- return out
- end
- -- Системное сообщение ИИ
- local messages = {
- { role = "system", content = [[
- You are an AI robot controller. Every 5 seconds respond with a JSON array of command objects
- for the robot to execute next.
- Example:
- [
- {"action":"move","direction":"forward"}
- ]
- Always output ONLY this JSON array without any additional text.]] }
- }
- -- Запрос следующего плана у ИИ
- local function plan_next(state)
- table.insert(messages, { role = "user", content = translate(json.encode(state), "en") })
- local payload = { model = "mistral-large-latest", messages = messages }
- local ok_req, resp = pcall(internet.request, MISTRAL_URL, json.encode(payload), headers)
- if not ok_req or not resp then error("Connection error to AI API") end
- local raw = "" for chunk in resp do raw = raw .. chunk end
- local ok_dec, dec = pcall(json.decode, raw)
- if not ok_dec or not dec or not dec.choices then error("Invalid AI response: " .. raw) end
- local reply = dec.choices[1].message.content
- table.insert(messages, { role = "assistant", content = reply })
- local ok_json, cmds = pcall(json.decode, reply)
- if not ok_json then error("Failed parsing commands: " .. reply) end
- return cmds
- end
- -- Мысли ИИ: публикуем в чат
- local function think_and_say(commands)
- local thought = "Thinking to execute: " .. json.encode(commands)
- if chat then chat.say(translate(thought, "ru")) end
- end
- -- Исполнение команд на роботе
- local function execute(commands)
- for _, cmd in ipairs(commands) do
- if cmd.action == "move" then
- if cmd.direction == "forward" then
- if not robot.forward() then robot.swing() robot.forward() end
- elseif cmd.direction == "back" then
- robot.back()
- elseif cmd.direction == "up" then
- if not robot.up() then robot.swingUp() robot.up() end
- elseif cmd.direction == "down" then
- if not robot.down() then robot.swingDown() robot.down() end
- end
- elseif cmd.action == "turn" then
- if cmd.direction == "left" then
- robot.turnLeft()
- elseif cmd.direction == "right" then
- robot.turnRight()
- end
- elseif cmd.action == "moveTo" then
- nav.goTo(cmd.x or 0, cmd.y or 0, cmd.z or 0)
- elseif cmd.action == "scan" and radar then
- radar.getEntities()
- elseif cmd.action == "distance" and camera_comp then
- camera_comp.distance(cmd.x or 0, cmd.y or 0)
- elseif cmd.action == "distanceUp" and camera_comp then
- camera_comp.distanceUp(cmd.x or 0, cmd.y or 0)
- elseif cmd.action == "distanceDown" and camera_comp then
- camera_comp.distanceDown(cmd.x or 0, cmd.y or 0)
- elseif cmd.action == "say" and chat then
- chat.say(cmd.message or "")
- elseif cmd.action == "shutdown" then
- computer.shutdown()
- end
- end
- end
- -- Основной автономный цикл
- while true do
- local pos = { nav.getPosition() }
- local state = {
- energy = computer.energy(),
- position = { x = pos[1], y = pos[2], z = pos[3] },
- facing = nav.getFacing(),
- radar = radar and #radar.getEntities() or 0,
- front = camera_comp and camera_comp.distance() or nil,
- up = camera_comp and camera_comp.distanceUp() or nil,
- down = camera_comp and camera_comp.distanceDown() or nil
- }
- local ok_plan, commands_or_err = pcall(plan_next, state)
- if not ok_plan then
- log_error("Plan error: " .. tostring(commands_or_err))
- else
- think_and_say(commands_or_err)
- local ok_exec, exec_err = pcall(execute, commands_or_err)
- if not ok_exec then log_error("Execute error: " .. tostring(exec_err)) end
- end
- os.sleep(5)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement