Hello all once more.

I've been out for quite a while, but I've recently discovered that turtles can now identify blocks and items on their own.
This lead to a neat idea I've been wanting to try out, but I had to make a few subcomponents first.

This is a "Logistics API"; if you're wondering about the name: I was kind of inspired by the Logistics Pipes mod.

Anyways, this API provides facilities for the following:
  • Persistent location (spatial and facing)
  • Automatic GPS
  • Item Tracking ("turtle X at position (x,y,z) has items Y, Z, and A")
  • Item Transfer
  • Task Scheduling / Planning ("move to (x,y,z), stay there for a few seconds, then go to (a,b,c) and rendezvous with turtle Y to get item Z….")
  • Data Networking (the API uses floodfill networking internally)
The API is centered around a list of tasks the turtle will do at some point in time.
These tasks can be anything from simple waiting to a "rendezvous" (item transfer transaction).

Functions:
  • bootstrap() – Initialize the API (get position, initialize modems, etc.). Call this before doing anything else with the API.
  • set_rendezvous( id, op_type, vec, item, count) Schedule an item transfer with a turtle. op_type must be either "get" or "put"– "get" will cause the other turtle to put items into the calling turtle, while "put" does the opposite. Vec is a vector (using the Vector API) to a place to perform the rendezvous; this area should be clear, and the area directly above this vector should also be clear. Item and Count compose the list of items to transfer. Each element of one list corresponds to the same-indexed element in the other. Entries in Item should be names returned by turtle.identify or turtle.getItemDetail. For example,
    
    set_rendezvous( 9, "put", vector.new( 55, 12, 15 ), { "minecraft:stone", "minecraft:sign" }, {1, 2} )
    
    would cause the calling turtle to move to (55, 12, 15) and place a Stone Block and a Sign in turtle 9 (os.computerID())'s inventory.
  • schedule_move_to( vec, time_spent) – Schedule a move to the specified vector, and a subsequent wait.
  • wait_move_to( vec, time_spent ) – As above, but then wait for the move to actually take place.
  • schedule_static_rendezvous( vec, op, container, slot , count) – Schedule an item transfer with a "static" container (a chest, etc.). Op and Count are as with set_rendezvous(). Container is the name of the type of block to interface with, for example, "minecraft:chest". Slot is a list of slots to utilize when performing the request. Count can be an empty table; in this case, each slot will be completely emptied or filled, according to the operation. For example,
    
    schedule_static_rendezvous( vector.new(55, 66, 22), "get", "minecraft:chest", {1, 15}, {23, 56} )
    
    would cause the calling turtle to move to (55, 66, 22), and from an adjacent chest, retrieve 23 items to place in slot 1, and retrieve another 56 items to place into slot 15.
  • get_current_pos() – get a vector representing the turtle's current (x,y,z) coordinates.
  • network_search( items, types, counts ) Scan the network for turtles with the specified items. As with set_rendezvous() and schedule_static_rendezvous(), all three parameters should correspond to one another. Items is a list of items to search for, Types is a list of the type of item to search for (for now only the "item" type has been tested) and counts is a list of the minimum number of items to return when searching. For example,
    
    network_search( {"minecraft:stone"}, {"item"}, {32} )
    
    would search for all networked turtles that have at least 32 stone blocks somewhere in their inventories.
  • unit_query( id ) – Get information on a turtle.
  • push_moves() – Wakes up the move handler. Use this after scheduling moves (such as with set_rendezvous())
Return Value Formats:
This function uses objects heavily inside.
Two functions so far return objects:
  • network_search() – Returns a list of response objects of the format:
    
    { id = sender.id, resource = { <list of matched items> }, types={ <list of matched types for resource> }, count = { <list of counts of matched items> } }
    
  • unit_query() – Returns a list of response objects of the format:
    
    {
    id = <sender-id>
    inv= <sender-inventory>,
    unit_info=<unit-info-list>
    position=<unit-position>
    facing=<unit-facing>
    n_tasks=<unit-task-list-length>
    }
    
Here's one example program:

-- this simple example searches for stone blocks on the network,
-- performs a rendezvous with any turtles that have stone blocks,
-- and then puts the first two slots of the turtle's inventory in a chest.
local r = logistical_network.network_search( {"minecraft:stone"}, {"item"}, {0} ) -- look for turtles with stone blocks
local rVec = vector.new( 203, 60, -283 ) -- location to rendezvous at
local cVec = vector.new( 197, 56, -276 ) -- location of a empty space adjacent to a chest
for i=1, #r do
	logistical_network.set_rendezvous( r[i].id, "get", rVec, {"minecraft:stone"}, {r[i].count[1]} ) -- schedule a rendezvous at rVec
end
local last_id = logistical_network.schedule_static_rendezvous( cVec, "put", "minecraft:chest", {1,2}, {} ) -- put the items into the chest
logistical_network.push_moves() -- now go actually do everything

Get it here.
(pastebin code: yJAA43zd)



Yeah, this documentation is pretty sloppy, isn't it?
Well, to be frank, I think it's because this API's still kind of a work in progress. It works– more or less, however.

There's still a few issues to work out, though:
  • The rendezvous system is very sensitive to GPS trilateration errors. Any way of minimizing or eliminating this error automatically or semi-automatically would be greatly appreciated. I was looking into multilateration, but I can't figure out how to get that to work.
  • If tasks are spatially clustered (close together), then they sometimes get to the task site too early, which poses problems for rendezvouses (since they can time out).
  • I need to find a better way to route around obstructions that turtles should break (other turtles, computers, etc.). Right now the turtles just patiently wait for the obstruction to go away… which may never happen or might not happen fast enough.
There are also a few more things I'm working on or will be working on soon:
  • Rendezvous Chaining: Basically, bucket-brigade-style delivery of items from turtle A to turtle B over long distances. Turtles pass an item down a chain of other turtles, eventually arriving at a destination turtle. For example, turtle A rendezvouses with turtle X, who passes it on to Y, and so on and so on, until turtle N passes it on to the destination turtle B. The benefit of doing this as opposed to direct delivery is that it requires less travel time of each turtle, freeing them up for other requests sooner.
  • Crafting support: this would allow for the network to make items that are requested. Would require a hand-compiled list of recipes, though this shouldn't be too difficult.
  • Building support: It would be nice to have a swarm of building turtles that can automatically distribute building resources amongst themselves. Or a swarm that can mine and then transfer the resources to a building site immediately.
  • Refueling support: for whenever a networked turtle runs out of fuel (or to bootstrap newly-created turtles)
  • Better "Static Node" support: Probably will involve "beacon" computers that respond to network requests like turtles, but don't move. These would be used to advertise chests, furnaces, and other stationary inventories.
What I'm planning on making with all this:
  • Von Neumann Turtle Swarm: A self-replicating swarm of turtles that can make other turtles to add to the swarm. Would require mining and crafting support, as well as minimal building support.