Developing an Inventory Management System for Second Life Abstract Anthony Rosequist Workflow For the progress report a month ago, I set the goal to have a basic, functional inventory management system using the RFID system in Second Life. I wanted to be able to keep track of various inventory levels at various locations throughout the hospital, and I also wanted to be able to request the inventory of a particular item at a particular location ( how many blankets are at depot #1? ) and receive an accurate response. I am pleased that I was able to accomplish these goals while adding an extra feature: the ability to perform a much more general query (with a particular item and a particular quantity, like I need 5 blankets ) that responds with the depots you should visit to most efficiently gather your required items. 1. Problem The workflow team as a whole is focused on providing the most effective way to simulate human interaction in the Second Life hospital. The focus has been on nurse and patient bots, where a patient would make a request that should be fulfilled by the nurse. We were given a list of various workflows, with the goal of implementing several of them into Second Life bots. This involved various subproblems. One team worked on using LSL to code robots, while another experimented with the OpenMetaverse libraries and C# to see how much functionality they would provide. There were also individuals who developed languages (in Lisp and Prolog) to represent workflows in a more abstract construct. As for me, my focus was on using the already-existent RFID system in Second Life. I was going to build an inventory management system. The idea is that hospitals do not have one giant storage room to hold all of the supplies that they would ever need. Instead, there are multiple inventory depots scattered across the hospital. When a nurse needs to get some objects, it would be inefficient to walk to the furthest depot when a nearby one might have all of the objects she needs. To help solve this problem, a centralized inventory management system could be developed. It would keep track of all of the item inventories at all of the depots across the hospital. When a nurse needs an object, it could make a recommendation on the best depot(s) to visit. 2. Objective The objective of the workflow team was to implement several cohesive workflow procedures in Second Life, with the ultimate goal being a designed framework for workflow development on the Second Life island.
The objective of my subprobject was to make an easy-to-use inventory management system, with clearly specified procedure calls. The long-term goal is to have the bots use this to carry out their goals more efficiently. 3. Related Work The only related work I directly used was the RFID system that exists on the Second Life island. It contains an RFID Scanner and an RFID Tag. Although I experienced some problems during the semester with the objects not working correctly, they are stable overall and extremely effective. 4. Architecture 4.1 Design The overall design of the project was: Daniel and Evan worked on the Second Life object bots, primarily using the bot language developed by Nick Farrer. They were able to implement several workflows that work very well. For the avatar team, Taylor and Shawn focused on getting the OpenMetaverse C# code working to control their avatar bots. They have successfully gotten control of their avatars and can do many basic movements and other commands (such as animations). Clinton has created a GUI that allows the user to control the avatar bots from outside of the Second Life interface. This gives you a chance to decide exactly what is needed by your C# program without having to do trial and error and constant recompiling. May and Ralph have completed workflow translations into Prolog and Lisp, respectively. This involves creating the proper semantics for specifying workflows as well as actually converting the workflows from English. In the future, these will be used to control the object and avatar bots without having to worry about the underlying LSL and C# code. The design of my subproject was: A major decision was whether the inventory manager should reside internally (as a Second Life object) or externally (on a server). I chose to do it externally, for a few reasons. The primary reason was speed. Although an HTTP request must be made for every query, it is still much faster than LSL code. Since the algorithm requires some reasonably intense calculations, the difference between the two is substantial. Further, there are many limitations of LSL that would make it much more difficult (and errorprone) to implement the algorithm in it than a server-side language. Early on, I learned the difficulty of doing relatively simple things (like 2D arrays) in LSL, and decided against using it as the primary language. In Second Life, every inventory depot has a script to communicate with the server. Whenever its inventory changes (items are added or removed), it sends an update command to the server. There is also an object to make queries to the server. When the owner says something to the query object, it sends either a query or count command to the server, and tells the result to the owner (further detail on those commands are
below). Since the object must always be within listening range of the owner, it is recommended that the owner attaches the object somewhere to their screen (you can always make it transparent, so it seems like nothing is there). On the server side, a PHP script resides on my Turing account to intercept the commands from Second Life. However, the PHP script does not actually process the commands. Instead, it simply passes the instructions to a Java application, which does the actual work. I did this because I could implement the algorithm much faster (with fewer errors), and also because Java has several functions already built-in that I would have to recreate in PHP. Furthermore, the compiled Java code is probably significantly faster than the same algorithm in interpreted PHP code. The PHP script only reads one variable ( args ), from either GET or POST, which simply includes the arguments to pass to the Java application. Then, whatever result Java prints to stdout is sent back to the LSL script. The possible argument structures for the Java application are: 1. update depotname item,item,item,item,item x.xx, y.yy, z.zz A) This will update the server's inventory of a items at a particular depot. B) The depot's name is the first argument. The form is entirely irrelevant, as long as the same depot uses the same name for all server updates. Depots don't need to be created or initialized before sending updates if the server gets a request for a depot that doesn't yet exist, it will automatically create one. C) A comma-delimited (no spaces) list of items follows. If a depot held 2 blankets and 1 wheelchair, this list would be blanket,blanket,wheelchair. This format was chosen because it integrated well with the current RFID scanner code. The order of items is irrelevant. D) Finally, the depot's physical coordinates are entered. This includes three floating point numbers, where the first two are followed by a comma and a space. If the depot's location changes, it only needs to send an update command and the server will automatically alter the location. The location can be determined by llgetpos(), which returns a vector. A vector's string representation is <x.xx, y.yy, z.zz>. The only change that needs to be made is stripping the < and > from it (it interferes with the PHP portion). 2. count depotname item A) This will return the number of items a particular depot holds of a particular object. It is relatively straightforward. B) The depot's name is the first argument. If the depot doesn't exist, it will return zero. C) The item's name is the second argument. 3. query quantity item position
4.2 Testing A) This is the main user command. You pass a particular quantity of a particular item, and it will calculate the depots that you need to go to in order to minimize distance traveled, given your current location. B) The quantity is an integer representing the number of items you need. C) The item is a string of the item that you need. D) The position is your current location, determined by llgetpos(), with the < and > characters stripped (just like with the update command). E) This command returns a user-friendly Visit depots x, y, and z, where x, y, and z are the depots the user should visit. After writing the Java code, I ran multiple tests to ensure that it performed as expected. Then, I created the PHP script to pass the arguments to the Java application and print the stdout result. Next, I created simple Second Life objects to interact with the server script. Finally, I incorporated these LSL functions into the RFID Tag and RFID Scanner objects. I ran multiple tests under different conditions to ensure that it gave me reasonable results. 5. Results The testing proved successful. I placed RFID Scanners are three locations in the hospital, and then I placed various quantities of blankets and food trays in each depot. I ran various tests, moving items in and out of depots, flying to different areas, and requesting different quantities of different types of objects. In each case, it gave me predictable, reasonable results. I did some very limited error checking, such as moving directly into a scanner, requesting too many objects (more than the total that exist), etc. All of these seemed to work correctly, although the checks were not rigorous by any means. 6. Conclusions 6.1 Summary Overall, I believe that the project was a success. There are certainly vast amounts of improvements that can be made, but a foundation has been laid. I think that externalizing the processing was a good decision, at least in the short-term, because it allowed for faster, simpler, and more accurate code than I could produce using LSL. It also allows for a more structured and flexible code base than LSL does. 6.2 Impact As the bots (both LSL and avatar) become more advanced and plentiful, it is necessary to know where they need to go in a more abstract sense. Instead of go to waypoint x, the bot must say go to the location where 5 blankets are. In order to do that, an effective inventory management system is required.
6.3 Future Work Incorporating the functionality into the bots (either the LSL bots or C# avatar bots). The next big step would be to use this system for bots to determine where they should go to gather what they need. The ability to query multiple items at once. Ex) I need 2 blankets and 3 wheelchairs. Currently, distance is calculated between two points by simple Euclidean geometry. However, this is significantly different from the real world, where a nurse would have to worry about going around walls in order to get to a location. A method to determine the real distance would greatly enhance the practicality of the query function. The ability to reserve an item for you after requesting it. After saying I need 2 blankets, the inventory manager determines which depots you should go to, and automatically subtracts 2 blankets from their inventory, so that you are guaranteed that they will be there for you when you arrive. This is important when you allow bots to query the inventory management system, since they will assume that the items are available at the requested depots. Avoiding concurrency errors. The current application stores the list of depots (and their inventory) in an external file through serialization. Therefore, if two depots attempt to update their inventory simultaneously, one of them will fail. Since the depots send their entire inventory with every update, the depot that was ignored simply needs to re-try the request. However, the current structure does not allow detection of failures. Some method that would allow for concurrent updates would be beneficial. Adding a delete depot function. This would rarely occur in real situations, but it is still something that needs to be added. If a depot is simply deleted, all of its inventory is still saved by the inventory manager. This means that it will be considered when performing queries. Adding a method to delete a depot would be extremely simple, but it would be great if the Second Life object automatically send a delete request when the object was deleted (I'm not sure if this is possible). Optimizing the algorithm, either theoretically or in implementation. The structure was designed to ensure that the algorithm would work effectively. The combination of LSL>>PHP>>Java>>PHP>>LSL is probably extremely inefficient, and an attempt could be made to increase the performance. However, this does not seem like an urgent task, since we will be dealing with relatively small numbers of depots. A specific place to optimize the algorithm (asymptotically) would be to change the calculateminimumdistance method (the traveling salesman problem). Currently, it just calculates the distance of all possible permutations, which runs in O(n!) time. Dynamic solutions exist in O(n 2 2 n ), and non-exact solutions (like genetic algorithms) can run in even less time. Optimizing this method would help the program become more scalable. Currently, when queried, the application returns a list of depots to visit, in an irrelevant order. An extra feature (which would be indispensable for bots using the code) would be to output the depots in the order which the nurse should travel to minimize the total distance. This would be very easy to do, since the algorithm calculates this already. However, a few small structural changes would need to be made.
Appendix A query algorithm Here is a simplified, non-rigorous algorithm that was used for implementing the query functionality in the final application. A[ x][ y]=the minimum distance it takes to find y objects in the first x depots. V [ x][ y]=the list of depots to visit to achieve the minimum distance it take to find y objects in the first x depots. C [ x]=the count of the item in depot x. (given) { x i=0 C [i] y: A[ x][ y]= A[ x 1][ y] minimum distance for ( V [ x 1][ y C [ x]] depot x ): A[ x 1][ y] else: minimum distance for (V [ x 1][ y C [ x]] depot x ) V [ x][ y]={ x i=0 C [i] y: [ ] A[ x 1][ y] minimum distance for ( V [ x 1][ y C [ x]] depot x ): V [ x 1][ y] else : (V[x-1][y-C[x]] depot x ) It is important to note that this algorithm requires the use of a method to find the minimum distance between points in a list, ie the traveling salesman problem. Unfortunately, I could not find a way to restructure the algorithm to avoid this, so I simply implemented a bruteforce method to find the solution. Appendix B LSL functions The HTTPCommunicator.pdf file contains the source code for the LSL functions that send user requests to the server ( count and query ). It parses the user's speech, send the appropriate request, and tells the owner the response it receives. The RFIDScanner.pdf file contains the LSL code that updates the depot's inventory count when it changes in Second Life ( update ). Appendix C PHP script The DepotManager.php.pdf file contains the PHP source code. It is extremely simple, since it only passes the arguments onto the Java application, and prints the stdout result. Appendix D Java source code The Depot.pdf, DepotManager.pdf, and Point.pdf files contain the Java code for the Inventory Depot Manager application. It contains three classes: Point (to represent 3D coordinates), Depot (to represent a depot with a name, inventory, and location), and DepotManager (which holds all of the main methods to execute the program).
Comments What did you learn? I knew nothing about Second Life before taking this class, so I had to learn a lot about using it, from a user and developer point of view. LSL is the first event-driven language I have had to use, so changing paradigms took a while to get used to. What did you like about the class? I liked that the class was project-based. Having projects that you can be excited about certainly makes the class much better. I also enjoyed learning about some of the different programming language paradigms. What didn t you like about the class? While I like the projects, I slightly wish that we would have gone over just a little more of the programming language theory. Also, while the Second Life projects did prove to be educational, there was a very steep learning curve for those of us who have never used it before. Learning curves aren't a bad thing, but it did hamper a little bit of learning about languages and project progress, since it took a couple of months to get everything understood (at the same time, some of the learning curve was getting used to LSL, which is certainly relevant to the course).