Part 69: Assignment #AC1: The Ocean's Bounty
The Ocean's BountyIt turns out my new office is very similar to my old one: a fairly cozy room with a tablet and a nice camera view of the outdoors. On the other hand, the outdoors itself is pretty stunning. Sun had the foresight to site Avalon City in a good latitude, so it's always warm.
You can also tell from the picture I showed in the last post - the city's nowhere near finished yet. Avalon City is built on a series of hexagonal 'plates' that are apparently modular on a grand scale (this explains the six-way traffic intersections), but all the plates aren't in place yet - in particular, a number of plates for the residential and industrial sectors are still missing. So for the time being, I'm camping out in my office.
That said, I'm near to the food! So to speak. Those aquaponics plants I helped design the control systems for are up and running, but they're designed for quickly growing large quantities of one or two kinds of fish and plants. Avalon City's diet isn't exactly monotonous- the closest cafeteria's fishcakes are pretty good - but it could be better. On top of that, (Sun alluded to this in his welcome email) the aquaponics systems need supplies for the cleaning tools and to keep the tank water in balance, so they're not truly self-sufficient... there's a whole bunch of stuff.
In short: Sun had the aquaponics plants made so you could feed a lot of people - quickly - and that's exactly what they're doing. But no more than that.
Which is why I'm helping a bunch of biochemists make a robot arm that carries crates to and from their freezer.
Lisa's the team head. I haven't met her in person yet I got roped into this by meeting Derrick at the welcome party but she seems fairly upbeat.
I should probably also mention that saying "a bunch of biochemists" was a bit of a misnomer. Derrick's actually a mechanical engineer, and a lot of the other team members (though I haven't exactly met many yet) are from different disciplines, though it does skew towards biochemistry and engineering. Apparently, a lot of the teams here in Avalon City are pretty multidisciplinary.
Now here's what I'm actually making:
I can already see the basic idea of the design. There'll need to be 1-2 MCs that control the movement - move/grab/drop itself; a memory chip to remember where everything is, and a MC to manage it; and possibly other MCs to respond to the radio or whatever. The spec they gave me has five 'slots' in it, but Derrick said he'd appreciate it if the design was customizable for as many slots as necessary. I told him yes - as long as he'd be OK with using a larger memory chip for 15+ slots.
The first prototype shouldn't be too hard to make. I'll get right on it.
[ ~ ]
This is my first attempt.
It came out pretty much as I envisioned; the top left MC responds to the radio. It'll send two values to the MC below it (which is attached to the memory chip): a value to search for in the RAM chip, and what to put in that memory slot in place of the value that the MC found. When adding a new crate, the value to search for is '0', which represents an empty slot. The value to write is the crate's ID number, representing it being stored. When removing a crate, it's the other way around; the value to search for is the crate's ID number, and '0' is written over it, to represent that slot becoming empty.
The memory-chip MC keeps track of what crate is where. It will respond to the radio MC's 'search' request, find a matching slot, and update the memory chip accordingly (sadly, due to Pingda Co.'s memory chips' auto-increment feature, it has to spend a lot of lines carefully moving the memory pointer back by one). Then, it'll signal the arm MC (the third MC6000, over on the right) with two values: which slot it should move to and grab a crate (starting from '1' and counting up), and where it should move that crate to ('0' being the loading dock).
The arm MC will do the moving job when signaled, controlling the motor directly. The smaller MC just to the right of it controls the arm extension and claw - sending it '100' (or almost any value) will make it grab, while sending it '0' will make it release.
The arm MC does use a bit of cleverness to get the job done. Depending on whether it's loading or unloading a crate, it has to tell the grab MC to either grab the crate at the loading dock (before the arm starts moving) and release it in the storage area, or grab it in the storage area and release once it's back at the loading dock. The grab and release at the loading dock are handled through conditional flags (the mov 100 x2 and mov 0 x2 lines), but I save a line of code by saying mov dat x2 - the value stored in dat will always be '0' in the case of a crate being added, and it will be the crate's ID# in the case of a crate being removed. So, the grab MC will drop (0) the crate in the storage area on a 'store' command, and grab (not 0) the crate from there on a 'retrieve' - just as designed.
This design does have a few tiny quirks. First off, there can never be a crate with an ID# 0, though that's really a permanent design choice (as 0 is reserved for 'empty slot'). More importantly, this design currently codes for 5 slots. By changing the number on the "#limit" line of the memory-chip MC, you can get up to 13 slots, or 32 with a larger memory chip. (The last slot of the memory chip has to remain unused because the arm MC receives the address of the slot after the target slot in the memory chip, and uses that address number to know how far to move the arm. If the last slot is used, the address of the next slot will be '0', and the arm will return the crate to the loading dock.)
The total cost: ¥20, with 417 average power per run. This is the first job I've had in a long while where I don't have to specifically worry about optimizing for something cost isn't a concern here, and power only a minor one but I'll try to clean up the design as much as I can, anyway. One thing that's tugging at me is the empty space on the radio MC - I could switch the MC to a MC4000, except for the fact that it needs both the acc and dat registers. I'll move things around and see if there's an alternate way I can do this...
[ ~ ~ ]
My second prototype turned out a little bit different from my first! The main change here is that the radio MC is now responsible for writing the value to the memory chip. The MC that was originally the dedicated memory-chip MC now only searches for the crate or empty slot's location.
The way things work now is as follows:
First, the radio MC receives a message, then it sends the value to look for (be it an empty slot (0) or a crate's ID#) to the searcher MC4000X, just below. The searcher MC will check the memory chip for the value, then send the address pointer of the memory chip (pointing to the cell after the found value, 'cause of how memory chips' pointers work) to the grab MC. It will also send a '1' to notify the radio MC it's time to write.
The radio MC, once it receives the pulse from the searcher MC, will rewind the address pointer, then write the value (be it empty slot or crate ID) in the correct slot. Effectively, most all of the work I've done here is moved the writing code to the upper MC without really changing it all that much.
The arm and grab MCs are also the same as my first version, so the rest of the design works as I described above.
By moving the code around and turning the memory-chip MC6000 from the previous version into the searcher MC4000X in this one, I managed to save ¥2, while keeping the power about the same. The new stats are ¥18, and 423 average power per run. I'm going to show the design to Derrick and get his take on it.
[ ~ ~ ~ ]
OK, this is a tad embarassing. When I explained my shiny new design to Derrick, he immediately asked about what would happen if someone tried to add to a full storage bay - or if someone tried to remove a crate that wasn't there, by accident. The answer: nothing good! (The arm wouldn't move, but the memory chip would still get written to as though it had been, and the record of whatever was in the last slot of the storage array could be corrupted.)
It turns out both problems have the same underlying cause: when the searcher MC looks for a value that isn't actually in the memory chip. If the storage area is full, there will be no '0' slots in the memory chip to write a crate ID# in, and if the wrong crate ID is requested, it won't be in the memory chip either!
So, I took my design back to add error handling capabilities. Here's the updated version:
This design has a few changes. The first is the error handling code, which is added to the radio and searcher MCs. The searcher MC now sends the radio MC the address of (the cell two places after) the found value - the radio MC will test this value, and if it's over the limit, it won't write anything.
A side effect of this change is that now the last two cells of any memory chip have to be left blank for it to work, enabling this design to serve up to 12 slots with a small memory chip, and 31 slots with a large one.
The second change makes the arm MCs more efficient, and is unrelated to error handling; I discovered it while fiddling around with the design. The new version of the arm MC delegates more of the grabbing control to the grab MC.
The grab MC, when cued, will now grab, wait for a specified time, then release automatically. (Previously, it had to be cued twice, once for grab and once for release.) This means the arm MC has to signal the grab MC only once during a run, giving a slight power savings.
The combination of the two improvements means the new design has better statistics than the old one - still ¥18, but 411 average power per run. My best yet! (Obviously, a run that triggers the error-handling code will be less expensive, as writing and arm-moving won't happen.)
I'll get ready to send this to the team.
[ ~ ~ ~ ~ ]
So I was going to show the previous design to Derrick, but I happened to take one more look at my original design, first. Then, inspiration hit me.
The reason I'd had to leave lots of free space on the radio MC, the first time around, was that I was using both of its registers. The thing is, I was using those two registers so that I could have the crate ID in one, and '0' in the other! Depending on whether the crate was supposed to be stored or retrieved, the radio MC might swap the crate ID between registers. Then, I'd send the registers out in a set order - so swapping the registers would change which value went out first.
I realized it didn't need to be this complicated. Since one of the values that's sent out is always a '0', those sends can be done with some 'mov 0 x1' instructions and conditional flags. This way, the design doesn't need to use registers at all - it can send the crate ID straight from the radio's buffer, and the '0' is hardcoded! In short: the radio MC can become a MC4000, pain-free.
I'm not actually sure why I did my first prototype the way I did, come to think of it.
Anyway, I'm pretty sure this is my final design. It brings together everything I've gathered from previous versions:
The radio MC is now at maximum efficiency.
The memory-chip MC will ask for both values ('0' and the crate ID) at once, to make sure that if nothing is found during the search, the radio MC isn't left hanging sending the second value. This version will perform proper error handling, and do nothing if a crate or empty slot is not found.
The arm and grab MCs are the updated, power-efficient design.
Because I've gone back to the old version, it can handle 13 or 32 slots total, depending on memory chip size.
Final statistics: ¥18, 397 average power per run. I think it's a pretty good little machine, and I can't wait to see it in action.
I am looking forward to this (eventual) 7-course french dinner! It's actually pretty exciting to be part of Avalon City's... well, bootstrapping phases, to put it simply. Even if I do have to do a little office camping for the time being, seeing the city come together is worth it.
And now I'm going to take a walk in the sunshine.