Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal

Molinko

Members
  • Content Count

    451
  • Joined

  • Last visited

  • Days Won

    35

Posts posted by Molinko

  1. Lua is single threaded. Meaning that only one chunck of code can ever run at a time. Coroutines are considered co-operative in that they yield to allow others to compute before they themselves finish. The idea is that we can do a little work we need right now and do it quickly, then yield so others can do the same, hence co-operative. Threads are fancy coroutines, but they are still limited to cooperation, so they must yield if you wish to begin another. Use term.read or io.read or os.sleep.... etc. 

  2. local c = require("component")
    local computer = require("computer")
    local internet = require("internet")
    local f = io.open("test.txt", "wb")
    
    local imax = 0
    local xmax = 75
    local ymax = 180
    local zmax = 87
    
    local TIMEOUT = 5  -- in seconds
    
    local link = "https://raw.githubusercontent.com/LordNocturnus/sf-"
    local folder = "/master/"
    
    local pos = 0
    
    for i = 0, imax do
      for xb = pos, xmax do
        for yb = 0, ymax do
          for zb = 0, zmax do
            print(xb, yb, zb)
            local file = xb .. "-" .. yb .. "-" .. zb .. ".mb3d"
            local url = link .. i .. folder .. file
            local status, connection = pcall(internet.request, url)
    
            if not status or not connection then
              print("Download of " .. url .. " failed.")
            else
              local startTime = computer.uptime()
    
              while true do
                local response, isFinished = pcall(connection.finishConnect)
                
                if response and isFinished then
                  break
                elseif not response then
                  print("Could not connect to " .. url .. ".")
                  os.exit()
                elseif computer.uptime() - startTime > TIMEOUT then
                  print("Request to " .. url .. " timed out")
                  os.exit()
                else
                  os.sleep(0.25)
                end
              end
    
              local f = io.open(file, "wb")
    
              for chunk in response do
                f:write(chunk)
              end
    
              f:close()
              connection:close()
            end
          end
        end
      end
    end

    Fixed some typos and made some things more readable. And a bug...

  3. Functions cannot* be sent over a modem. Only primitive types like strings, numbers or booleans can be sent raw. Tables can be serialized(turned into a string), but the same rules apply. Just send a command as a string or number that the drone will use as a command to call computer.shutdown on it's own.

  4. If you're trying to use the *same terminal window on two screens at once it can be tricky to do unless you know OpenOS as well as Payonel does. However, if you just want to be able you run one program on a secondary screen and be able to use a shell or run a program on another screen , then you can check out this thread I answered before. I think it might be helpful.

    similar question

  5. Debugging drones can be difficult but the analyzer will help you get an error message from crashed programs on microcontrollers. Seeing the code and where you say it crashes.. I'd say that indexing the supposed table `v` caused the error. Indexing being `v.name` or `v.x`. I suppose if v.x or v.z or v.y are nil then drone.move will likely throw an error. But it's hard to know without more info. Get that analyzer data and come back.

    Hell, just wrap the whole code in pcall and collect any errors.

    local d= component.proxy(component.list("drone")())
    local m= component.proxy(component.list("modem")())
    local r= component.proxy(component.list("radar")())
    m.open(1)
    
    local ok, err --# declare outside loop so we can get the value later
    
    when true do
    local rtable,mov,x,y,z = select(6, computer.pullSignal())
        if mov == "follow" then
        	ok, err = pcall(function()
                for k, v in pairs(r.getEntities()) do
                    if v.name == "PHOBOSS" then
                        d.move(v.x, v.y, v.z)
                    end
                end
            end) --# pcall end
        
            if not ok then --# we have an error
          	    break --# break the while loop
            end
        end
    end
    -- # send the error back to our controller and finish
    m.send(ourHost, port, 'ERROR: '..(err or ""))

     

  6. The linked card is one of the most expensive components next to the geolyzer when it comes to energy. Coroutines are actually really efficient because all other forms i.e loops are a "busy" waiting and thus consume power running functions, evaluating... os.sleep is essentially coroutines.yield. As for remote booting you should see the doc on modem.setWakeMessage

  7. local component = require("component")
    local event = require("event")
    local m = component.modem -- # make local too
    m.open(1) -- # 001 ??
    
    repeat
      -- # run in the loop to repeat reception of 'cmd'
      local cmd = select(6, event.pull("modem_message")) -- # this is cleaner
    until cmd == "stop"

     

  8. I'm running MC 1.12.2 with Computronics meant for 1.12.1 and although it works* I also cannot retrieve any player information from the radar. So I wouldn't call it a bug because I'm in the wrong version... but it's prob a bug...

  9. I totally forgot about fishing... I'll hop on in a bit and give this a shot :3

    -- Nope. I've tried several times but the robot never actually casts the fishing line. You can get robot.used to return true on the rod when its successful but even then you never see a fishing line nor any fish :(

  10. What you want is code that will "block" further execution until some condition is met. Because drone.move is non-blocking(pain in the ass if you ask me :p) we have to write  a function to wait until the drone is finished moving.

    function waitUntil(freq, predicate)
      -- # wait 'freq' amount of time until 'predicate' returns true
      repeat computer.pullSignal(freq) until predicate()
    end

    Can then apply it to your code like so..

    local r=component.proxy(component.list("radar")())
    local m=component.proxy(component.list("modem")())
    local d=component.proxy(component.list("drone")())
    d.setLightColor(0x00FFD8)
    m.open(001)
    
    function waitUntil(freq, predicate)
      -- # wait 'freq' amount of time until 'predicate' returns true
      repeat computer.pullSignal(freq) until predicate()
    end
    
    while true do
        local evt_,_,_,_,name,cmd,x,y,z = computer.pullSignal()
            if evt=="modem_message" then
                if cmd=="test z" then
                d.move(0,3,0)
                waitUntil(0.5, function() return d.getVelocity() == 0 end)
                d.move(0,-3,0)
                end
                if cmd=="test x" then
                d.move(3,0,0)
                waitUntil(0.5, function() return d.getVelocity() == 0 end)
                d.move(-3,0,0)
                end
                if cmd=="shh" then
                break
                end
            end
    end

     

  11. So I did some testing and I think what your approach is misunderstood. Once a Tunnel is placed into a Relay it cannot be addressed (as a component). It effectively becomes a part of the "physical" network layer. A better approach would be to place a Tunnel into a Relay on the "master" computer network (via some cable. the master has a modem inside). Your robot should have a wireless modem. And the third piece is a "Network extender".

    A "Network extender" consists of a Power Distributor component connected via cable to two Relay components (these must not touch each other nor can both directly touch the Power Distributor. Creates 'cycles'. Cycles are bad). A Relay is denoted with either a "R^"(Tunnel) or  "R*" for (Modem).

    Crap network diagram

    C : Computer                ^   : [Tunnel]          network interface
    R : Relay                   *   : [Wireless Modem]  network interface
    P : Power distributor       -|+ : Wired cable connection
    
                             P
                             |
        C1---R1^        R2^--+--R3*  ("Network extender")
    
                            C2*
    
    C1 is computer #1
    C2 is computer #2 (your robot)
    R[1-3] are Relay components

     

  12. Okay, so i worked something up for you. These two scripts should get you started. If you need something better you'll have to build it yourself :p

    Add these files to /home/,  /home/bin/,  or  /usr/bin/. Whichever you prefer.

    tmsp.lua  "term swap"

    local component = require "component"
    local term = require "term"
    
    local args, opts = require("shell").parse(...)
    local USAGE = [[
    Usage: $cmd [q, m, f, --gpu, --screen] [screen_address]
    $cmd -mf --screen=27f    include motd, flush screen
    $cmd -qf 27f --gpu=38a   quite mode, flush
    ]]
    
    if not term.isAvailable() then
      os.exit()
    end
    
    if not opts.screen and not args[1] then
      local cmd = require("process").info().command
      io.stderr:write(USAGE:gsub("%$cmd", cmd).."\n")
      os.exit()
    end
    
    local screen, err = component.get(opts.screen or args[1], 'screen')
    if not screen then
      io.stderr:write(("failed to get screen component")..'\n')
      os.exit()
    end
    
    local gpu
    if opts.gpu then
      gpu, err = component.get(opts.gpu, "gpu")
      if not gpu then
        io.stderr:write(("failed to get gpu component")..'\n')
        os.exit()
      end
    else
      gpu = component.gpu.address
    end
    
    if screen ~= term.screen() then
      if not opts.q then
        print "rebinding term screen.."
        os.sleep(1)
      end
    
      if opts.f then term.clear() end
    
      component.invoke(gpu, "bind", screen)
      term.setCursor(1, 1)
      term.bind(component.proxy(gpu))
    
      if opts.f then term.clear() end
    
      if opts.m then
        dofile("/etc/motd")
      end
    else
      if not opts.q then
        print "screen is already bound to term"
      end
    end

    alterm.lua "alternate term"

    local component = require "component"
    local process = require "process"
    local thread = require "thread"
    local event = require "event"
    local term = require "term"
    
    local args, opts = require("shell").parse(...)
    local USAGE = [[
    Usage: %s [-qf] --screen=5b3 --gpu=64f `program ...`
      -q: quiet mode
      -f: flush the target screen before and after program execution
    ]]
    
    if not opts.screen or not opts.gpu or not args[1] then
      local cmd = process.info().command
      io.stderr:write(USAGE:format(cmd).."\n")
      os.exit()
    end
    
    local gpu = assert(component.get(opts.gpu, 'gpu'))
    local screen = assert(component.get(opts.screen, 'screen'))
    assert(component.invoke(gpu, "bind", screen, opts.f))
    
    local proc = thread.create(function()
      local window = term.internal.open(0, 0, component.invoke(gpu, "getViewport"))
      term.bind(component.proxy(gpu), window)
      process.info().data.window = window
      if opts.f then term.clear() end
      os.execute(args[1])
      if not opts.q then
        print('exiting from background..')
        os.sleep(1)
      end
      if opts.f then term.clear() end
    end)
    
    proc:detach()
    
    if not opts.q then
      print(('backgrounded "%s" on gpu[%s] & screen[%s]'):format(args[1], opts.gpu, opts.screen))
    end

    Add these to your /home/.shrc file to start them after boot.

    Be sure to insert your own component addresses. Addresses may be abbreviated.

    tmsp -qfm --screen=45af --gpu=7ed2
    alterm -qf --screen=65ec --gpu=b9d3

     

  13. It is possible but mirroring in the precise sense is a bit tricky. If you just want to run a program on a screen and still have a shell in the remote terminal that's not that difficult. What are you trying to achieve? Do you really need mirroring? Or do you just want to be able to run more than one program at a time?

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.