Jump to content

turtlex v0.5.2 - smart turtle api - inventory + position tracking

turtle api

42 replies to this topic

#1 GopherAtl

  • Members
  • 888 posts

Posted 07 September 2012 - 04:25 PM

0.5.2:VERY minor tweaks, nothing you would even notice, made for increased compatibility with the native turtle API (ex, turtlex.turnLeft() returns true now, like the built-in turtle api function) and with my current project, ctrl, a higher-level turtle interface system that adds waypoint-based pathfinding and simple macro-style scripting, which will be released eventually.

0.5.1:minor tweaks only; added "REQ" header identifying inventory as a requirement (which I needed for my own automatic api loader, which has not been released), and added a hackish version of transferTo. Proper version coming.

More importantly, releasing a utility program for use with turtlex, called inv. Run from the shell, inv displays the contents of the turtle's inventory as a menu. It provides a method of manually setting up the inventory type names without doing it by calling turtle.setItemType from lua. See below for info on using it and a pastebin link to the program.

This is an api - well, a pair of them actually - I've been working on as part of a larger project. It replicates most of the functionality of the built-in turtle API, but adds code to most methods to provide position, direction, and inventory tracking.

You'll need both the inventory API and the turtlex APIs installed and loaded (os.loadAPI), and you'll want to load them in your startup file or at the start of the program that uses them. Inventory must be loaded first or turtlex will throw an error.


Version History

Utility programs
inv displays the inventory of the turtle and allows changing the item type names. The controls are displayed on-screen, but for reference:

arrow keys - move the selection around in the inventory.
enter - edit the name of the current item. Enter again saves the new name. Entering a blank line will cancel the edit.
space - forces an update of the inventory, useful when you have added, removed, or transfered items in the turtle's inventory while running inv.
tab - exits to the shell

inventory API - http://pastebin.com/yp00iTji
turtlex API - http://pastebin.com/SYhqiJTk
inv (utility program) - http://pastebin.com/BTTRKswG
go http://pastebin.com/EpLB5vrH replacement for standard go command, identical except uses turtlex, so that your turtle doesn't lose track of it's position when caled.

Sample installation process

#2 Sebra

  • Members
  • 726 posts

Posted 15 September 2012 - 06:13 AM

Seems good but...
Where are no functions to tell turtle it's current position? What if you want it GPS synchronized with others?
Why attack() functions ignored? They can change inventory.

#3 GopherAtl

  • Members
  • 888 posts

Posted 15 September 2012 - 07:12 AM

I am developing this for a specific project, which requires robust position tracking without gps or human intervention, hence those omissions. Attack functions, I've never even called before, so yeah, just didn't think to implement them. All of these things will be addressed eventually, got sidetracked with the logo project and now building some other code to go back and rewrite this with. Things I've implemented in the last two nights:
  • surefile - a simple api that provides routines for writing of state information to files in a verifiable way - so you're guaranteed to load back a valid status even if the program is interrupted in the middle of an update, and if an update was interrupted during save, know that on loading so you can compensate for any error it would've introduced.
  • goroutine API - for managing coroutines, which adds several features over the basic parallel api, including...
    • spawning additional coroutines on the fly
    • methods to wait not just for an event type but to filter those by any of the event's parameters as well (so no looping over pullEvent checking if it's YOUR timer, you can just do waitForEvent("timer", myTimer)
    • passing parameters to the initial call of the coroutine function
    • methods to assign a type of events exclusively to one coroutine over the others.
  • worker API - I'm not gonna try to explain this right now because it's late and I'm tired, but it will provide a common interface for the assignment and execution of tasks to and by turtles, including managing a task queue, reporting on the current status, and state saving for resuming where it left off.
Anyway, will eventually be rewriting turtlex to use surefile and to be compatible with (but not require) the worker API. I was possibly a bit premature in sharing this library, though I have tested it with a couple of mining programs. There's been no comments, so I assumed nobody was trying to use it, or I would've made a higher priority of adding missing features like gps support.

#4 jasonb42

  • New Members
  • 2 posts

Posted 17 September 2012 - 03:50 AM

This API is amazing! I've done something similar but this exceeds where I've gotten, plus the code clean and well formatted.
There are two enhancements I am interested in:

Optional function parameter for each move command
Each individual successful move would call the passed in function.

GPS verification of location at startup
This would verify current position and direction, as long as the signal strength is strong enough and the turtle can move in any x/y direction.

Would you be interested in collaborating on some of these enhancements? I am pretty busy for the next couple days but could work on it after that.

#5 GopherAtl

  • Members
  • 888 posts

Posted 17 September 2012 - 05:30 AM

Thanks! Im pretty pleased with the code so far. I've deliberately put off gps support so I can really get the self tracking as robust as possible. The posted version was almost guaranteed to be off on position or direction if a program was interrupted while moving, but no more! Rewrote the position saving this weekend, think its about as reliable as possible now, so I'll probably add gps support this week. Also added some new functionality, I'll update the post with a link to the new source and list of the new features soon. Includes enhancements to drop and getItemCount, plus an iterator for looping over all slots containing items of a given type.

The optional function to run after each move is a good idea, thanks for the suggestion! As for collaboration, feel free to make any encancements you like and share the code here. New features that really add something valuable I may incorporate into my version, crediting you of course!

Despite what I said last post, after thinking about it, I'm going to try to avoid making turtlex depend on any of my other APIs at all. I'm using it in more elaborate projects, but I want it to remain usable as just a replacement for the turtle API as well.

Anyway, new version will be posted soon, and thanks for the feedback and suggestions!

#6 Sebra

  • Members
  • 726 posts

Posted 17 September 2012 - 05:37 PM

View Postjasonb42, on 17 September 2012 - 03:50 AM, said:

Optional function parameter for each move command
Each individual successful move would call the passed in function.
I think using events is quite better.

#7 GopherAtl

  • Members
  • 888 posts

Posted 17 September 2012 - 05:42 PM

That's on the feature list as well, but if that function is going to have any turtle commands, event handlers in a separate coroutine would not work. Simple example, if you called forward(10) and passed a function that digs up, down, left, and right, you'd wind up with two coroutines giving conflicting commands to the turtle and the whole program would break, so there's cases for both approaches.

#8 jasonb42

  • New Members
  • 2 posts

Posted 17 September 2012 - 06:02 PM

View PostGopherAtl, on 17 September 2012 - 05:42 PM, said:

That's on the feature list as well, but if that function is going to have any turtle commands, event handlers in a separate coroutine would not work. Simple example, if you called forward(10) and passed a function that digs up, down, left, and right, you'd wind up with two coroutines giving conflicting commands to the turtle and the whole program would break, so there's cases for both approaches.

To clarify why I specified a passed function (events would be useful for other cases) here is one example use case:
You specify a movement path around your tree farm. Every move calls the function harvestTree() which:
  • If a tree has grown in the next spot:
    • pushPop() the current position
    • Move up harvesting the tree, plant a new sapling, etc.
    • popPos() to return to it's start position
  • Returns, so program can continue moving around tree farm
You could also potentially use the function in a mining turtle to drop off inventory/refuel but there might be better ways to handle those cases.

#9 Sebra

  • Members
  • 726 posts

Posted 17 September 2012 - 06:53 PM

You tell it to go 10 m forward and each meter it should check for a tree? Find a better solution.

#10 GopherAtl

  • Members
  • 888 posts

Posted 17 September 2012 - 07:09 PM

no need to be snarky, it was just an example. Point is, if the per-step action involves any turtle code, a callback function is required instead of an event.

#11 Sebra

  • Members
  • 726 posts

Posted 18 September 2012 - 05:36 PM

In my opinion if calling program knows what to do on each step it should move step by step.
Events are usable by other handlers. For movement tracking, world exploring, boundaries checking...
In other words calling program do not know about it.

#12 GopherAtl

  • Members
  • 888 posts

Posted 18 September 2012 - 06:00 PM

eeh, you could just loop calling turtlex.forward(1) n times instead of turtlex.forward(n), but you would lose some of forward's functionality, like the onFail="return" option that makes the turtle return to it's starting point in the event of a failure, and for turtlex.goto or turtlex.move, you lose even more, since you'd have to reproduce the complex iterative structures it does internally if you were moving one step at a time.

There will, as I said, also be events, for cases where events will do the job, but anything involving the turtle is an exception. Some more examples include laying track or pipe along the path from point A to B or examining the blocks around it and mining any that match carried samples.

#13 dadmob18

  • New Members
  • 15 posts

Posted 04 October 2012 - 04:13 AM

I really like your concept here! Wrapping the turtle functions to track position and inventory is such a generally useful utility for almost any other turtle task. I was starting to do it myself when I found your post. One angle I was taking was to get rid of all those Up/Down/Forward/Back variations on the methods and add a first argument instead, one of "U", "D", "B", "F", so you just need to write move, detect, dig, etc. once instead of three or four times. Anyway, just a thought. It seemed to help clean up my functions.

I can't tell if you also can track inventory in chests with your library, or just the turtles.
Edit: oh yes, I see you can inventory.create(nSlots) for a chest or any other inventory, nice.

Keep up the good work!

#14 GopherAtl

  • Members
  • 888 posts

Posted 12 October 2012 - 03:29 PM

The inventory api is separate because I eventually intend to use it for chest inventory management as well, I haven't really tried using it that way even myself, and the dropTo and suckFrom methods on an inventory object are not very thoroughly tested yet. In theory, dropTo updates the inventory object's contents based on the logic the game uses to place items in slots, though naturally it depends on the inventory being up-to-date and the item types all being consistent; if you dropped "unknown1" into a chest that already contained an "unknown1" it would expect them to stack, and if one was dirt and the other cobble, obviously they wouldn't. Also, if you dropped dirt labeled "unknown1" into a chest that had dirt labeled "dirt" it would NOT expect them to stack. These are part of the reason I haven't been using the inventory api except for turtles, who can do compareTo to identify and correct this sort of issues.

I considered taking parameters to specify directions, but decided instead to mirror the turtle api's approach. Eventually, I am considering setting it up to override the turtle api, so that existing programs written for turtle will use turtlex instead.

Should be uploading a new version of this tonight. I've added support for gps - it attempts to verify it's position with gps every 8 moves, as well as checking position on startup, but otherwise continues to use it's own tracking, so it won't be affected by storms or moving out of range of the gps hosts. Also added an optional monitor server, which it reports it's position to at fixed intervals; by default it's nil, and it sends no reports, but you can call turtlex.setMonitorIID() with the id of a computer (or other turtle) and it will send periodic updates to them. Currently only sends its position every 8 moves. Before I upload it, I also plan on finally fixing the issue with many of the commands, including forward(), that causes them to throw an error if called with no parameters, when they should be falling back to on the standard turtle api behavior (in the case of forward, moving 1).

Anyway, glad you like the api, thanks for the feedback!

#15 ChunLing

  • Members
  • 2,027 posts

Posted 13 October 2012 - 09:51 PM

Why not just use an array of single chests, each chest only having a single item type, for the work of ensuring consistent loadouts on the turtles? Then you can have "dump" chests for excess/unidentifiable items. You can have sorting turtles that have single item stacks filling their inventory and can go over the dumps, sucking up anything that stacks with their existing inventory, then go to the chests of identified items and turtle.drop(turtle.getItemCount(slotNum)-1) so that they keep a single item in the identified stack.

That way most of the turtles can just dump stuff off in the dump chests, then the sorting turtles sort it all out.

You can have a central database that gets a rednet message every time a turtle dumps, saying how much in how many stacks, so that the sorting turtles can just check dumps that are getting full, to save on movement/fuel. Or you can have 9 turtles surrounding the chest, with 144 different item types, sucking on the chest whenever a dump occurs and returning to the identified chest array when they are full of something. Or you can use a combination of both techniques.

Regular (mining) turtles will have about half their inventory 'reserved' for specific item types and half left open for unidentifiable (to that particular turtle) items. When they start getting items in slot 16 they visit the nearest dump chest. For efficiency, you could have the dump chests be chest carts on rails with a powered cart on either side of the train. When the train was getting full/emptied, a turtle would just place a lump of fuel in the powered cart at the end to send the train up to 500 meters (much more efficient then having a turtle carry stuff all the way back, particularly since each chest cart can carry more and you can have a whole train of them).

#16 CoolisTheName007

  • Members
  • 304 posts

Posted 14 October 2012 - 11:26 PM

I am re-writing a program to control a reactor and a breeder simultaneously, and your goroutine API is just what I need to use virtual RP2 timers correctly. Do you still have it somewhere?

#17 GopherAtl

  • Members
  • 888 posts

Posted 15 October 2012 - 03:49 AM

Chum, yes, separate chests are actually what I tend to use, which is why I haven't worked on the inventory API anymore.

I'll eventually release the goroutines API, there's a couple of things I wanted to change in it first. I might go ahead and release the current version later, though, if there's interest.

#18 Nommy

  • New Members
  • 2 posts

Posted 26 October 2012 - 07:52 PM

I'd also be interested in seeing/using the goroutines API and the other stuff you've done GopherAtl. Thanks for posting what you have already. I briefly started something a little while back using turtlex and thought it was great - clean and clear compared to other scripts. In fact the I only came was here to see if you'd posted any updates or new stuff since a lot of the stuff you talked about having done or working on sounded similar to things I had in mind and I was hoping to find some more goodies. I've still got my fingers crossed on that one :D/>

Also I had one suggestion / idea while I was trying out the turtlex before: In gpsUpdate(), check for air before moving into that space, so as to not accidentally destroy water/lava source blocks.

Thanks again, looking forward to seeing more.

#19 ChunLing

  • Members
  • 2,027 posts

Posted 26 October 2012 - 09:41 PM

Water blocks aren't such a big deal, but some people do find lava valuable. The solution I prefer is to use a water source above a deep excavation, so that all the lava is turned into obsidian, but in tunnels and such this is not as feasible (it's still possible, just not very easy).

#20 Nommy

  • New Members
  • 2 posts

Posted 27 October 2012 - 12:09 AM

No, it's certainly not a big deal, just a suggestion. I was thinking more along the lines of water used in sugarcane farms or in fountains etc which you wouldn't want accidentally destroyed if gpsUpdate() happens to be run by a turtle going past when the server restarts or you quit single player.

The turtlex.place() functions did not seem to include any method of specifying sign text so I added a parameter in each:
I only briefly tested turtlex.place("Sign", "message"), and I'm new to this, so keep that in mind. It seemed to work ok though.

1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users