If you install a lot of programs, you may find that your context menu (the list that appears when you right-click) has a bunch of junk on it or takes a few seconds to load. Fortunately, it's pretty simple to clean up the global context menu.
Open regedit with Windows+R "regedit" and accept the UAC confirmation. Navigate to HKEY_CLASSES_ROOT, then the folder whose name is a single asterisk "*", then "shellex", then expand the folder names "ContextMenuHandlers". Every subfolder (subkey) of that is one program's group of entries that shows up on your context menu everywhere. Simply right-click and choose Delete on an entry to remove it. (If there is an entry that looks like a mash of hexadecimal characters in curly braces, some app developer tried to register entries manually and misunderstood how this key works. Those entries can be deleted.)
Fun fact: using the .NET Framework in a context menu handler is a great way to produce insane slowdowns whenever the user right-clicks. Developers, please don't. .NET is great - I love it - but loading the CLR takes what is an unacceptable length of time for right-click responsiveness.
Various technical articles, IT-related tutorials, software information, and development journals
Tuesday, December 30, 2014
Monday, December 29, 2014
Accessing Windows Storage Volumes by GUID
Suppose you have a storage volume whose drive letter is variable, but you need a consistent means of addressing it. (Like a flash drive that has something you need to access from a batch file.) You could use the whole WMIC-forloop-findstr business to get the letter, but then you have environment variables that need to be cleaned up. Or maybe you just don't want to deal with that whole thing and would rather just access the drive by a unique intrinsic property of it.
You can get the drive's GUID by typing "mountvol" at a command prompt. At the end of its help spew, it tells you all the volumes that the system sees at the moment:
Right click in the window and choose Mark, highlight the whole GUID line (the \\?\Volume{...}\ thing), and hit Enter to copy it. This path can sort of be used as a directory, with the following major limitations:
You can get the drive's GUID by typing "mountvol" at a command prompt. At the end of its help spew, it tells you all the volumes that the system sees at the moment:
Right click in the window and choose Mark, highlight the whole GUID line (the \\?\Volume{...}\ thing), and hit Enter to copy it. This path can sort of be used as a directory, with the following major limitations:
- You can't cd to it (even with PowerShell)
- You can't mount it with net use
- You can't get to it with pushd
- Almost no application will open files on it
The only thing you can reliably do is dir it (adding a second backslash to the end if you want its root directory) and copy files from it. Copying to and from it, however, lets you do basically anything - just copy a file off, edit it however you want, and copy it back it.
Sunday, December 28, 2014
Abiathar Confidential - GameMaps with VeriMaps Signature Format
Abiathar, as of v2.2, includes the VeriMaps feature, which alters the format of the emitted GameMaps file to some degree. I am describing its format here so that any other editors or tools can read and write the modified format correctly.
First, if a GameMaps file is an Abiathar VeriMaps file, its first eight bytes are "FleexRSA". (If that signature isn't there, no special considerations are necessary for 100% compatibility with Abiathar.) The signature is immediately followed (there's no null terminator after "FleexRSA") by the name of the signer, which is ended with a null. After that is the 128-byte RSA signature.
Before parsing any level data, read the entire rest of the file (starting immediately after the signature) into a buffer. Append the name of the signer to this string:
https://dl.dropboxusercontent.com/u/3771470/Abiathar/VeriMaps/
And add ".acert" to the end to get the URL of the user's public key. (You can test for connection using "VeriMaps.txt" in that directory, which should contain the string "Abiathar".) The first line of that file is the user's distinction/title or "NUL" if they have no distinction. The second line is the XML representation of a .NET RSAParameters object that can be created like this:
Dim sFile As New IO.StreamReader(Path)
Dim distinction = sFile.ReadLine
Dim rsa = Security.Cryptography.RSA.Create()
rsa.FromXmlString(sFile.ReadToEnd)
sFile.Close()
Dim rsaParams = rsa.ExportParameters(False)
Compute the SHA-512 hash of the GameMaps file data. Compare it to the signed version that came with the file using this function:
To create signed VeriMaps files, use an ASIGN (signing certificate) file provided by the user. The first line is the user's name; the second is the XML RSAParameters with private key data included. After writing the main GameMaps data region, calculate its hash and sign it using RSAPKCS1SignatureFormatter.
First, if a GameMaps file is an Abiathar VeriMaps file, its first eight bytes are "FleexRSA". (If that signature isn't there, no special considerations are necessary for 100% compatibility with Abiathar.) The signature is immediately followed (there's no null terminator after "FleexRSA") by the name of the signer, which is ended with a null. After that is the 128-byte RSA signature.
Before parsing any level data, read the entire rest of the file (starting immediately after the signature) into a buffer. Append the name of the signer to this string:
https://dl.dropboxusercontent.com/u/3771470/Abiathar/VeriMaps/
And add ".acert" to the end to get the URL of the user's public key. (You can test for connection using "VeriMaps.txt" in that directory, which should contain the string "Abiathar".) The first line of that file is the user's distinction/title or "NUL" if they have no distinction. The second line is the XML representation of a .NET RSAParameters object that can be created like this:
Dim sFile As New IO.StreamReader(Path)
Dim distinction = sFile.ReadLine
Dim rsa = Security.Cryptography.RSA.Create()
rsa.FromXmlString(sFile.ReadToEnd)
sFile.Close()
Dim rsaParams = rsa.ExportParameters(False)
Compute the SHA-512 hash of the GameMaps file data. Compare it to the signed version that came with the file using this function:
Public Function CheckSignature(SignedHash As Byte(), _
Hash As Byte(), Cert As RSAParameters) As Boolean
Dim rsa As New RSACryptoServiceProvider rsa.ImportParameters(Cert) Dim deform As New RSAPKCS1SignatureDeformatter(rsa) deform.SetHashAlgorithm("SHA512") Return deform.VerifySignature(Hash, SignedHash) End Function
To create signed VeriMaps files, use an ASIGN (signing certificate) file provided by the user. The first line is the user's name; the second is the XML RSAParameters with private key data included. After writing the main GameMaps data region, calculate its hash and sign it using RSAPKCS1SignatureFormatter.
Saturday, December 27, 2014
DPAPI Doesn't Protect Much Data
You may have heard of the Windows Data Protection API, or DPAPI for short. Unfortunately, it doesn't protect much unless you're on a computer that people aren't using and don't have any access to, like a server.
The thing is, DPAPI encrypts the "protected" data with a per-user key that is kept secret by the OS kernel. This sounds really nice until you find out that every process running as the user can utilize DPAPI to encrypt and decrypt data belonging to that user. What's more, physical access to the computer can be exploited to get the machine key, which can be used to decrypt the user keys, which can be used to decrypt any data belonging to them. Data can also be DPAPI-encrypted with the system key, which allows any application running on the computer to decrypt it.
The situation is made slightly better by the possibility of adding "entropy" to the encryption. Of course, that must also be used to decrypt the data. What you then get is a chicken-and-egg problem: it's impossible to securely store the second key because you have no way of safely encrypting it.
So, DPAPI might be a tiny bit more secure than plain text - it might not be immediately obvious to an attacker that you're using it - but it's impossible to keep a secret inside one machine.
The thing is, DPAPI encrypts the "protected" data with a per-user key that is kept secret by the OS kernel. This sounds really nice until you find out that every process running as the user can utilize DPAPI to encrypt and decrypt data belonging to that user. What's more, physical access to the computer can be exploited to get the machine key, which can be used to decrypt the user keys, which can be used to decrypt any data belonging to them. Data can also be DPAPI-encrypted with the system key, which allows any application running on the computer to decrypt it.
The situation is made slightly better by the possibility of adding "entropy" to the encryption. Of course, that must also be used to decrypt the data. What you then get is a chicken-and-egg problem: it's impossible to securely store the second key because you have no way of safely encrypting it.
So, DPAPI might be a tiny bit more secure than plain text - it might not be immediately obvious to an attacker that you're using it - but it's impossible to keep a secret inside one machine.
Friday, December 26, 2014
Reading SQLite Databases from .NET
Today, I needed to use .NET to read data in an SQLite database. I found a really nice open-source project for doing that, called System.Data.SQLite. However, it took me a while to figure out how to get it working after deployment (i.e. not run from Visual Studio).
I kept getting BadImageFormatException and other errors like side-by-side configuration issues that are utterly incomprehensible to me as a managed-only developer. It turns out that the SQLite DLL is really touchy about .NET version and processor architecture, which makes sense considering it's a mixed mode (managed and native together) assembly. It's super important that you get the right binary package - I recommend the "Precompiled Binaries for 32-bit Windows (.NET Framework 4.0)" download because 64-bit OS's can run 32-bit programs and .NET 4.0 is usable on Windows XP and later.
In your project settings in Visual Studio, set your project to compile to x86 only (an option in the Compile tab). If you need 64-bitness, use that only and deploy the x64 version of SQLite.
Then, you have to keep the manifests and config files with your compiled programs when you deploy. The stuff about the VSHOST process attachment and the PDB's can be removed, but all the other supplementary stuff has to stay for SQLite to figure out how to run.
Once you have it compiling and running deployed, the SQLiteConnection and SQLiteAdapter class can be used just like other ADO.NET providers to get your data into DataTable instances.
I kept getting BadImageFormatException and other errors like side-by-side configuration issues that are utterly incomprehensible to me as a managed-only developer. It turns out that the SQLite DLL is really touchy about .NET version and processor architecture, which makes sense considering it's a mixed mode (managed and native together) assembly. It's super important that you get the right binary package - I recommend the "Precompiled Binaries for 32-bit Windows (.NET Framework 4.0)" download because 64-bit OS's can run 32-bit programs and .NET 4.0 is usable on Windows XP and later.
In your project settings in Visual Studio, set your project to compile to x86 only (an option in the Compile tab). If you need 64-bitness, use that only and deploy the x64 version of SQLite.
Then, you have to keep the manifests and config files with your compiled programs when you deploy. The stuff about the VSHOST process attachment and the PDB's can be removed, but all the other supplementary stuff has to stay for SQLite to figure out how to run.
Once you have it compiling and running deployed, the SQLiteConnection and SQLiteAdapter class can be used just like other ADO.NET providers to get your data into DataTable instances.
Thursday, December 25, 2014
How to Write and Compile USB Rubber Ducky Scripts
I just acquired a USB Rubber Ducky, a keystroke injector for all manner of computing devices. It took a bit of research to pick up all the knowledge necessary to get started with it, so I have written a short compilation here.
First, you'll need to remove the MicroSD card from the device, which is surprisingly difficult. Wiggle the card around a little and try to slide it out with your thumb. After the first time, it gets easier. Insert the card into your computer. If you don't have a MicroSD slot, use a MicroSD-to-USB flash-drive-ifier adapter, which may have come with your Rubber Ducky.
You'll find on the card a single file called inject.bin. This is the payload that will be executed when you plug the device into a computer. It's a proprietary binary format, so it's not easily modified directly. Instead, you write a text file in DuckyScript, which is a fairly intuitive scripting language. This text file is then compiled into the inject.bin by DuckEncode, a cross-platform executable JAR file.
I recommend creating a Windows batch file to do the compilation, since JAR files can't be drop targets by default. I made a compile.bat file that is just this line:
java -jar duckencode.jar -i %1 -o inject.bin
Place that in the same directory as the DuckEncode,jar you downloaded earlier. You can then drop any DuckyScript file onto the batch file and it will emit inject.bin from the script, which you can then move onto the device.
DELAY 2000
GUI r
DELAY 200
STRING notepad
ENTER
DELAY 400
STRING Hello!
First, you'll need to remove the MicroSD card from the device, which is surprisingly difficult. Wiggle the card around a little and try to slide it out with your thumb. After the first time, it gets easier. Insert the card into your computer. If you don't have a MicroSD slot, use a MicroSD-to-USB flash-drive-ifier adapter, which may have come with your Rubber Ducky.
You'll find on the card a single file called inject.bin. This is the payload that will be executed when you plug the device into a computer. It's a proprietary binary format, so it's not easily modified directly. Instead, you write a text file in DuckyScript, which is a fairly intuitive scripting language. This text file is then compiled into the inject.bin by DuckEncode, a cross-platform executable JAR file.
I recommend creating a Windows batch file to do the compilation, since JAR files can't be drop targets by default. I made a compile.bat file that is just this line:
java -jar duckencode.jar -i %1 -o inject.bin
Place that in the same directory as the DuckEncode,jar you downloaded earlier. You can then drop any DuckyScript file onto the batch file and it will emit inject.bin from the script, which you can then move onto the device.
DELAY 2000
GUI r
DELAY 200
STRING notepad
ENTER
DELAY 400
STRING Hello!
Wednesday, December 24, 2014
FMod - v2.3
I made a small adjustment to the Dreams levels loading code that will allow Abiathar to automatically fill in the compressed level header length if that section of the map header is missing or truncated (probably by The Omegamatic). This makes the FxTomDMh utility obsolete.
After making that change, I wrote up some documentation for v2.3 (as I have decided to call this release), wrote a changelog/release post on PCKF, and pushed it out with the auto-updater.
After making that change, I wrote up some documentation for v2.3 (as I have decided to call this release), wrote a changelog/release post on PCKF, and pushed it out with the auto-updater.
Tuesday, December 23, 2014
FMod - Helpful
One serious problem that I had identified with Abiathar was the lack of discoverability of its amazing features. The "did you know?" tips on the tools helped a little, but I can't be throwing them around all the time and they are also too small to provide detailed guides. People don't want to download and read a 40-page PDF to learn about this stuff; they just want to use whatever tool they just opened.
So, I removed most of the tip pop-ups from the tools (all the ones that appear at start-up are still there) and created a new panel for contextual help. Each tool can report what commands it can receive at a given point and provide any instructions that the user might need. The entire thing can easily be switched on or off at any time by pressing the question mark key or choosing Help | Contextual. It can be set to be turned on at startup through a config entry under DefaultViewSettings. I added contextual help for all the tools; I'm guessing it makes using them a lot easier for people who don't have the code right in front of them.
(The tool tips that were left on the Tile Property Modifier and Tile Instance Remapper say something to the effect of "this tool is really hard to use; you probably want to enable contextual help.")
I also identified and fixed several bugs while doing this:
So, I removed most of the tip pop-ups from the tools (all the ones that appear at start-up are still there) and created a new panel for contextual help. Each tool can report what commands it can receive at a given point and provide any instructions that the user might need. The entire thing can easily be switched on or off at any time by pressing the question mark key or choosing Help | Contextual. It can be set to be turned on at startup through a config entry under DefaultViewSettings. I added contextual help for all the tools; I'm guessing it makes using them a lot easier for people who don't have the code right in front of them.
(The tool tips that were left on the Tile Property Modifier and Tile Instance Remapper say something to the effect of "this tool is really hard to use; you probably want to enable contextual help.")
I also identified and fixed several bugs while doing this:
- The "did you know?" pop-up looked really out-of-place, being the normal Windows Forms colors on top of the intense blue on black of the initial screen.
- The tool status text was lost when switching to the tile palette and back.
- The Tile Property Modifier left its status text behind after being canceled.
- The Tile Property Modified left the animation target highlight behind only when switching to the Palette Copier.
- The Tile Instance Remapper was extraordinarily inconvenient to use because it reset the find buffer whenever plane states were changed.
All these changes might be worthy of the version number "2.3" rather than "2.2.1", but I'm not sure yet. What I am sure of is that these changes make using Abiathar a whole lot easier for new users.
Monday, December 22, 2014
FMod - Did You Know?
Today, in addition to starting my Music Appreciation winterim class, I continued working on what will be the v2.2.1 Abiathar update. From talking with an important user on IRC, I discovered some problems with the Patches dialog, which I thought was extremely simple! Apparently, his patch file's size exceeds the TextBox default max length of 32KB, so I increased the limit to 1MB, which should be more than enough for everyone. Also, the TextBox control does not by default make Ctrl+A select all, so I had to add that feature manually.
Then, I actually did something with the "did you know" tip boxes that I implemented yesterday. I wrote a collection of helpful tips, one of which is randomly chosen and displayed at start-up. Since the overlay is actually another form, I had to make keypresses on it forward to the main form. Then I discovered that when it passes the handling onto the main form, the dialog boxes created in the press handling are owned by the tip form, which destroys itself after a few seconds, taking the dialogs with it. So, I had to manually pass the main form to every ShowDialog call.
Some of the tools also show tips when they are first activated. Unfortunately, some of them are so extraordinarily complicated that useful help can only be found in the documentation. For those, I may need to pop off a live assistance pane.
Then, I actually did something with the "did you know" tip boxes that I implemented yesterday. I wrote a collection of helpful tips, one of which is randomly chosen and displayed at start-up. Since the overlay is actually another form, I had to make keypresses on it forward to the main form. Then I discovered that when it passes the handling onto the main form, the dialog boxes created in the press handling are owned by the tip form, which destroys itself after a few seconds, taking the dialogs with it. So, I had to manually pass the main form to every ShowDialog call.
Some of the tools also show tips when they are first activated. Unfortunately, some of them are so extraordinarily complicated that useful help can only be found in the documentation. For those, I may need to pop off a live assistance pane.
Sunday, December 21, 2014
FMod - Fix the Overwrite Bug
Through thought-experiments, I discovered what is probably a very annoying bug in Abiathar. If all the sounds are exported and then some IMF songs are imported with Song Mappings, those later changes will be lost if the full sound set is re-imported (unless the IMF song there was also updated).
I added a last-modified date for the IMF songs, stored in the dependency file. When a song is added modified with Song Mappings, the current time is written to the chunk's entry in this table. When importing the full sound set, the file's last-modified date is checked against that of the existing song. If the file is not newer than the existing song, the data is reused from the old audio resource before it is overwritten by the recompiled version. I also added a warning to the Audio Files dialog that should prevent people from accidentally blowing away their song mappings and extra songs; the mistake was easy enough to make that I did it myself.
I also found a subtle yet major problem with the Freeform Tile Placer that made it behave exactly like the Tile Tweaker. Somewhere along the way, its tool initializer had been changed to only listen for mouse movements if a certain Keen:Next emulation feature was enabled. That was easy enough to fix, and I'm surprised nobody noticed. (Though the main person who wanted it always uses all the Keen:Next emulation features.)
Finally, I built infrastructure for helpful and hopefully unobtrusive "did you know?" tips.
I added a last-modified date for the IMF songs, stored in the dependency file. When a song is added modified with Song Mappings, the current time is written to the chunk's entry in this table. When importing the full sound set, the file's last-modified date is checked against that of the existing song. If the file is not newer than the existing song, the data is reused from the old audio resource before it is overwritten by the recompiled version. I also added a warning to the Audio Files dialog that should prevent people from accidentally blowing away their song mappings and extra songs; the mistake was easy enough to make that I did it myself.
I also found a subtle yet major problem with the Freeform Tile Placer that made it behave exactly like the Tile Tweaker. Somewhere along the way, its tool initializer had been changed to only listen for mouse movements if a certain Keen:Next emulation feature was enabled. That was easy enough to fix, and I'm surprised nobody noticed. (Though the main person who wanted it always uses all the Keen:Next emulation features.)
Finally, I built infrastructure for helpful and hopefully unobtrusive "did you know?" tips.
Friday, December 19, 2014
Cryptographic Verification of Backwards Time Travel
In every sci-fi show where a character goes back in time, a whole bunch of time is spent convincing everyone that he is indeed from the future. In the unlikely event that this sort of thing happens in real life, we should have a way to quickly determine whether someone is truly from the future without all the hassles we see on TV.
I propose a small government ministry, possibly a service or subsidiary of NIST, whose sole purpose is to generate, store, and release asymmetric-cryptographic keys. Each day, this agency generates several asymmetric key pairs and publishes all the public keys. The private keys are kept private for a time, then released after the following intervals:
I propose a small government ministry, possibly a service or subsidiary of NIST, whose sole purpose is to generate, store, and release asymmetric-cryptographic keys. Each day, this agency generates several asymmetric key pairs and publishes all the public keys. The private keys are kept private for a time, then released after the following intervals:
- 1 day
- 3 days
- 1 week
- 1 month
- 6 months
- 1 year
- 2 years
- 5 years
- 20 years
- 50 years
- 100 years
- 200 years
Everybody should keep (or have a device that keeps) the most recently released private key for each day. Upon being transported back in time, the traveler can use the private key for the day in which he finds himself to encrypt a challenge text from those who wish to verify his traveling. The challengers can then decrypt the challenge text with the day's public key, and if the decryption succeeds, the traveler holds the private key and did indeed go back in time. It is possible to verify about how far in the future the traveler was by the last private key he has for the day.
The entire system relies on the security and longevity of the time service. Everybody would have to carry their key management device with them all the time, but it could be as unobtrusive as a small flashlight on a key ring. Of course, the entire idea of time travel is kind of far-fetched, so implementing this system be entirely pointless. You never know, though...
The entire system relies on the security and longevity of the time service. Everybody would have to carry their key management device with them all the time, but it could be as unobtrusive as a small flashlight on a key ring. Of course, the entire idea of time travel is kind of far-fetched, so implementing this system be entirely pointless. You never know, though...
Thursday, December 18, 2014
Robotics - Ramp Reassemble
We finally got the linear bearings 3D printed and attached. (That actually happened on the meeting last Saturday, which I could not attend.) The builders worked on mounting the lift assembly to the robot and tested operating the lift with string.
Meanwhile, I and several other non-engineers worked on fixing the ramp that had been assembled inside-out and backwards. We went down to the local hardware store and bought longer rivets and long screws for the builders. With the new rivets, we were able to - after a good deal of spatial finagling - rivet the pieces of the ramp together. It actually took four people and almost an hour of working together to make it happen.
We started attaching the side pieces to the ramp, but we ran out of time and didn't have all the brackets ready.
Meanwhile, I and several other non-engineers worked on fixing the ramp that had been assembled inside-out and backwards. We went down to the local hardware store and bought longer rivets and long screws for the builders. With the new rivets, we were able to - after a good deal of spatial finagling - rivet the pieces of the ramp together. It actually took four people and almost an hour of working together to make it happen.
We started attaching the side pieces to the ramp, but we ran out of time and didn't have all the brackets ready.
Wednesday, December 17, 2014
Speeding up Throttled Download Sites
I'm sure you've experienced the free download sites that throw boatloads of ads in your face and make your downloads excruciatingly slow unless you pay a possibly-not-so-small amount of money to upgrade to the "premium" experience. I've discovered an interesting method of speeding up these throttled downloads, at least a little bit:
Close the tab that created the download. In my experience, once the tab is closed and the connection is severed to the controlling web site, the download speeds up. The only reason I can imagine for this is that they don't want to risk giving their paying customers slow speeds, so once the HTTP session is lost, the speed goes back to normal. Of course, it should be very easy to have different servers for the different groups, so maybe it's just a placebo. Try it though - it might help somewhere.
Close the tab that created the download. In my experience, once the tab is closed and the connection is severed to the controlling web site, the download speeds up. The only reason I can imagine for this is that they don't want to risk giving their paying customers slow speeds, so once the HTTP session is lost, the speed goes back to normal. Of course, it should be very easy to have different servers for the different groups, so maybe it's just a placebo. Try it though - it might help somewhere.
Tuesday, December 16, 2014
Internet Routing Issues
Something has gone wrong with an upstream router, and I am only able to access a few of the sites I need to use for my normal operations. I can't find a pattern in the sites that work and those that don't. They all resolve normally in DNS, but I can't push any traffic through to them. I've power-cycled my router, but problems persist. Mediacom tech support could not identify the problem, and it has not been fixed in the three hours in which they said it would be.
Fortunately, I can access all important sites through proxies and onion-routing networks. It's really inconvenient, though, and I hope Mediacom fixes it soon.
Fortunately, I can access all important sites through proxies and onion-routing networks. It's really inconvenient, though, and I hope Mediacom fixes it soon.
Saturday, December 13, 2014
Removing Mysterious BlockAndSurf Ads from Chrome
I recently had the pleasure(?) of cleaning a number of adware programs off a Windows 7 laptop, including BlockAndSurf, sometimes known as Block-N-Surf, Re-Markable, or a whole host of other names. I used the ever-helpful MalwareBytes Anti-Malware and newly-discovered Hitman Pro to purge most of the horribleness from the machine, but the BlockAndSurf ads still lingered on many pages even though there was no Chrome extension for it or any other auto-start entry. It turns out that BlockAndSurf infects Chrome in some deep way that requires a complete uninstallation (remove browsing preferences, history, everything) and hosing of the directories in which it kept program files. After I ripped out every trace of Chrome and re-installed it, the ads were finally gone.
Friday, December 12, 2014
Managing User Accounts in Windows 8 Without the Metro
I am personally not a fan of the presence of two divergent Control Panel-ish areas in Windows 8. I just want my normal desktop Control Panel that has all the functionality I could ever want. Unfortunately, the Metro PC Settings app seems to be the default for managing "easy" settings, which apparently includes user accounts. There's still the User Accounts applet in Control Panel, but to add new users you have to go to PC Settings.
As a side note, in the configuration page for a user account in this applet, there is still a link to one of the most pointless dialogs in Windows:
("Change Type" just lets you choose between a local account and... nothing. The other option, "roaming", is always disabled unless you're on a domain with roaming user profiles.)
So, rather than dealing with that or PC Settings, I choose to use the administrative tools! (Woo, enterprise software.) If you're using Windows 8.1, right-click the Start button and choose Computer Management. Otherwise, it can be found under Administrative Tools in the desktop Control Panel. Under Local users and Groups, click the Users folder to see all the users of the computer. Add a new one with Action | New User. To promote a user to administrator, open its properties and add the Administrators group to the Member Of list.
Metro avoided and admin tools used. Nice!
No, I want to add a new user right here. |
You can literally do nothing from here besides go where you already are. |
So, rather than dealing with that or PC Settings, I choose to use the administrative tools! (Woo, enterprise software.) If you're using Windows 8.1, right-click the Start button and choose Computer Management. Otherwise, it can be found under Administrative Tools in the desktop Control Panel. Under Local users and Groups, click the Users folder to see all the users of the computer. Add a new one with Action | New User. To promote a user to administrator, open its properties and add the Administrators group to the Member Of list.
Metro avoided and admin tools used. Nice!
Thursday, December 11, 2014
Where to Find WIM Files for Deployment
It took me a long time to figure this out, but the Microsoft-proprietary WIM installation image files can only be acquired from the OS install discs. If you're deploying Windows 7, insert the Windows 7 disc that you have and pull the Boot.wim and Install.wim out of the "sources" folder. If you have an ISO of the install disc, just extract those files with your archive management program of choice.
Wednesday, December 10, 2014
Robotics - Solder It
Since it's a lack of lifting mechanism that's holding up our progress in robotics, we decided to start working on one despite not having the materials we need. We were expecting to have the linear slides 3D printed by now, but the facilitator of that is sick. So, we pulled out the contraptions that we started making at the last meet and tried to replicate them. We applied ThreadLock to the screws because there isn't a place to put nuts. These small assemblies were applied to the channels we have, and they seem to be doing a decent job of holding it together. We have yet to see whether it can be telescoped out by a motor.
Last week, we discovered that our field was set up backwards. Today, we discovered that the ramp's walls were reversed as well (to accommodate our misconception of the field layout). Not only that, we put the ramp plastic pieces together upside-down, so the arrangement of rivet holes was totally wrong. We got a drill and took the entire ramp apart - it was all wrong. We started putting it together the right way, but we need to find longer rivets.
Finally, I and one other member with little to do once the ramp was disassembled found the large bags of LEDs (that we ordered last year to use all our budget) and started soldering them to wires as practice and for fun. We didn't know that the length of the wires coming out of the LED mattered, so it was trial and error figuring out which way the circuit needed to go. We hooked it up to a triple-A battery from my calculator to see a slight red glow.
Last week, we discovered that our field was set up backwards. Today, we discovered that the ramp's walls were reversed as well (to accommodate our misconception of the field layout). Not only that, we put the ramp plastic pieces together upside-down, so the arrangement of rivet holes was totally wrong. We got a drill and took the entire ramp apart - it was all wrong. We started putting it together the right way, but we need to find longer rivets.
Finally, I and one other member with little to do once the ramp was disassembled found the large bags of LEDs (that we ordered last year to use all our budget) and started soldering them to wires as practice and for fun. We didn't know that the length of the wires coming out of the LED mattered, so it was trial and error figuring out which way the circuit needed to go. We hooked it up to a triple-A battery from my calculator to see a slight red glow.
Tuesday, December 9, 2014
Why "Server Operators" and "Backup Operators" are Equivalent to "Administrators"
Alternatively titled "Why SeRestorePrivilege Should Be Called SeTakeOverTheDomainPrivilege"
On Windows domains, there are special built-in groups called Server Operators and Backup Operators. Backup Operators are allowed to log on to domain controllers and access all the files everywhere for the purpose of backing them up. Server Operators are glorified Backup Operators, except that Server Operators can format hard drives, manage some services, and shut down the server remotely.
Both these groups hold SeBackupPrivilege and SeRestorePrivilege. SeBackupPrivilege, when activated by the user, is essentially an overriding Allow entry on GENERIC_READ for every DACL ever. In other words, holders of this privilege can read and copy every single file, including the full Active Directory or SAM databases. Depending on your credential storage hash strength, you may have handed all the passwords over to the Operators.
More importantly, SeRestorePrivilege allows the holder to write to anything anywhere, update any DACLs, and set any file metadata. This could be abused to lay a logon script trap for a full Administrator, or just use the sethc.exe trick to elevate to SYSTEM on a domain controller and do whatever to the Active Directory. Registering services to run as SYSTEM would work equally well.
As a side note, the Print Operators group has SeLoadDriverPrivilege, which allows a user to register user- or kernel-mode drivers. That ability opens up any number of system takeover avenues, so Print Operators are also just Administrators who haven't realized it yet.
You can learn all about the built-in groups and their privileges in TechNet's "Default groups: Active Directory" article.
So, you might want to reconsider adding semi-trusted people to these groups. They're pretty powerful once they realize it - it's not a large jump from any type of Operator to Administrator.
On Windows domains, there are special built-in groups called Server Operators and Backup Operators. Backup Operators are allowed to log on to domain controllers and access all the files everywhere for the purpose of backing them up. Server Operators are glorified Backup Operators, except that Server Operators can format hard drives, manage some services, and shut down the server remotely.
Both these groups hold SeBackupPrivilege and SeRestorePrivilege. SeBackupPrivilege, when activated by the user, is essentially an overriding Allow entry on GENERIC_READ for every DACL ever. In other words, holders of this privilege can read and copy every single file, including the full Active Directory or SAM databases. Depending on your credential storage hash strength, you may have handed all the passwords over to the Operators.
More importantly, SeRestorePrivilege allows the holder to write to anything anywhere, update any DACLs, and set any file metadata. This could be abused to lay a logon script trap for a full Administrator, or just use the sethc.exe trick to elevate to SYSTEM on a domain controller and do whatever to the Active Directory. Registering services to run as SYSTEM would work equally well.
As a side note, the Print Operators group has SeLoadDriverPrivilege, which allows a user to register user- or kernel-mode drivers. That ability opens up any number of system takeover avenues, so Print Operators are also just Administrators who haven't realized it yet.
You can learn all about the built-in groups and their privileges in TechNet's "Default groups: Active Directory" article.
So, you might want to reconsider adding semi-trusted people to these groups. They're pretty powerful once they realize it - it's not a large jump from any type of Operator to Administrator.
Monday, December 8, 2014
Converting a Physical Computer into a Virtual Machine
I was given the task today of taking a physical server and jamming it into a virtual machine that can be easily transported and backed up. Fortunately, this process is easier than the reverse.
VMWare Player
If you want to make a VMWare Player virtual machine, you'll need to use Norton Ghost, which comes on the free Win8.1SE boot disc. Burn that ISO to a DVD and use it to boot the machine, which may take up to 10 minutes. You'll need a huge flash drive, an extra hard drive, or a bunch of network storage to put the disk image in. Run Ghost from the Win8.1SE taskbar. Choose Local, then Disk, then To Image. Navigate to the storage place, choose VMDK from the file type dropdown, type the filename, and begin the imaging. If it asks you for a compression method, I recommend Fast.
Once Ghost shoves the disk into an image file, move the VMDK to the computer that will host the VM. Create a new VM with the following settings:
VMWare Player
If you want to make a VMWare Player virtual machine, you'll need to use Norton Ghost, which comes on the free Win8.1SE boot disc. Burn that ISO to a DVD and use it to boot the machine, which may take up to 10 minutes. You'll need a huge flash drive, an extra hard drive, or a bunch of network storage to put the disk image in. Run Ghost from the Win8.1SE taskbar. Choose Local, then Disk, then To Image. Navigate to the storage place, choose VMDK from the file type dropdown, type the filename, and begin the imaging. If it asks you for a compression method, I recommend Fast.
Once Ghost shoves the disk into an image file, move the VMDK to the computer that will host the VM. Create a new VM with the following settings:
- "I will install the operating system later"
- Select your OS from the lists
- Name your VM
- "Split virtual disk into multiple files" and set the maximum disk size to 1GB
- "Finish"
Once the wizard closes, select the blank VM from the list and open its settings. Delete the SCSI hard disk and add a new Hard Disk device. "Use an existing virtual disk" and select the VMDK file Ghost created. Try exposing the disk to the VM as whatever type of disk it was in the real machine, but if it fails to boot, use IDE - that always seems to work.
If the machine is a server of any sort, change the Network device from NAT to a bridge.
Start the virtual machine. You're done!
VirtualBox
I'd say VirtualBox is easier to deal with than VMWare because it can handle all manner of virtual disk formats, including the very convenient VHD. You could use Ghost like in the VMWare instructions and create a VMDK, or use Disk2Vhd, which uses Volume Shadow Copy and can perform the imaging while the system is online. Start Disk2Vhd in the running OS on the target computer. Make sure "Use VHDX" is not checked and "Use Volume Shadow Copy" is checked. Choose the storage place to save the large file, choose all the volumes on your drive, and click Create. Once the imaging is complete, move the VHD to the VM host system.
Launch VirtualBox and create a new VM. Choose your OS (this is really important in VirtualBox) and configure the computing power available to the VM. Use an existing virtual disk and select the VHD file you created with Disk2Vhd. If it's a server, make sure that the network adapter is a bridge, not NAT.
If there are any problems on boot, you may need to change the hard disk controller type. It should be the same as the physical disk, or IDE if that doesn't work.
Start the virtual machine. You're done!
Sunday, December 7, 2014
Looking at Strings with VMMap
As I was perusing the Windows Sysinternals Administrator's Reference, I learned about VMMap, a Sysinternals utility that inspects the memory allocations of a running process. One of its features is the Strings dialog, which presents a list of all the text strings (including Unicode) it could find in the loaded images (e.g. EXE, DLL). You can scroll through the list to discover all the things the program could say or think about, like error messages or parseable commands.
I used it on Abiathar and was very interested by the groupings of the texts. It seems the .NET compiler places string literals from the same methods and classes together for the most part. All the possible splash screen messages were together starting at 0x0037BAD8 in the executable file, 0x0086D6D8 in the process address space (but that might move around, I'm not sure). It also sees the strings compiled into the programs and files embedded in Abiathar, like the KeenGraph executable and the game maps files. The .NET compiler seems to write the names of all the methods, even if they're declared Private.
Some strings in Abiathar, from the Level Inspector subroutine |
You can download the Sysinternals Suite from its Microsoft TechNet subsite.
Saturday, December 6, 2014
Setting up Network Policy and Access Services on Windows Server with One Network Interface
I had the pleasure of configuring the Network Policy and Access Services role on a Windows Server 2008 machine a while ago. I did run into a small problem: the machine has only one Ethernet port, and the configuration wizard for NPAS wants you to select two different interfaces, one Internet-facing and one internally-facing.
(It didn't help that the initial NPAS configuration wizard was really hard to find. You have to right-click the server icon under the NPAS role and choose "Configure and Set Up", not pick it from the Action menu.)
The solution is to choose the Custom role configuration in that first wizard page. All the other combinations of installed features will ask for two different interfaces. After choosing Custom, just tick the boxes for all the features you need. All your network interfaces (the single real one, any fake virtualized ones, the loopback one, and an "internal" one) will be automatically detected and added. All non-loopback and non-internal interfaces will support NPAS, so you might need to disable it on some if you don't want it messing with your virtual machines.
(It didn't help that the initial NPAS configuration wizard was really hard to find. You have to right-click the server icon under the NPAS role and choose "Configure and Set Up", not pick it from the Action menu.)
The solution is to choose the Custom role configuration in that first wizard page. All the other combinations of installed features will ask for two different interfaces. After choosing Custom, just tick the boxes for all the features you need. All your network interfaces (the single real one, any fake virtualized ones, the loopback one, and an "internal" one) will be automatically detected and added. All non-loopback and non-internal interfaces will support NPAS, so you might need to disable it on some if you don't want it messing with your virtual machines.
Friday, December 5, 2014
Robotics [MEET] - Competition Take II
Today was the second meet of the season, and we again didn't hold high hopes for our performance. Work continued on the cardboard ball routing tubes, but we didn't attach the servo to the box because we have no lift. We have no lift because the 3D printer that we left to run last night got jammed and failed to produce the linear bearings. What it did produce was a sheet of flat domino-like things that are entirely useless as any kind of bearing.
While tinkering and messing around, one engineer discovered that a crazy arrangement of screws, nuts, C braces, and a washer performs passably as a linear bearing when a similarly crazy assembly is stuck onto the end of the channels. He worked on putting that together over the course of the meet, but it was never attached.
Our first match (which was also the first match of the night) was a total disaster. Our NXT battery was critically low because the other team needed the full battery (that we had been using) to pass software inspection. They never gave it back to us. Somehow, the simple autonomous program (that just drives forward from the ramp) vanished from the NXT, so we ran the complicated IR-involved one despite starting on the ramp. Since one of the drive motors' wires had gotten loose, the robot turned at the start, falling sideways off the ramp rather than driving down it. It did fully leave the ramp, so we got the points! Unfortunately, that fall knocked out the other motor's cable, rendering us inoperable. Our alliance partner was trying to move the tubes, but without much success. When they tried to climb the ramp, they fell off the side, but since the side of their robot that went off the ramp fell onto our disabled robot, they were fully off the floor and got the points.
It was about this time when we noticed that the real field layout was reversed from our practice field. This inconvenient fact rendered our IR-smart autonomous program entirely useless.
Despite that, we tried using the program in our second match. By sheer luck, it got really close to the kickstand, but missed it. We helped our alliance partner push tubes up the ramp, but our acrylic number plate got jostled loose. One corner fell to the floor and got jammed in the squishy mat, rendering us unable to move forward and only allowing very slow backward movement. We managed to park in the parking zone.
We used that same autonomous routine again to get down from the ramp, and it worked since we had repaired the motor connections. We tried to move the tubes to the ramp, but jammed them all into the corner and also got a big penalty for pushing one through the opposing parking zone. We did extract one tube and started to push it up the ramp. Our robot just barely got up off the floor with a push from the alliance team.
In the fourth round, we just used the stationary musical autonomous program. We pushed several tubes up the ramp and ended the game teetering on the brink with one tube and our robot partially off the flat part of the ramp. The allied team very carefully parked in the parking zone.
Our fifth and final match was a huge jam. The allied team instructed us to play defense, so we did our best to block the opposing alliance from accessing their tubes. A flood of balls and the kicked-down kickstand tripped up our robot, and we got stuck near the opposing tubes. An opposing robot tried to drive through the mess and got stuck on top of one of our front wheels. Neither of us were able to move for the rest of the match.
Our performance here was not great. I think we won only one of our five matches (the second one). We did make some progress on the linear slide system, but our capabilities were largely unchanged from the first meet.
While tinkering and messing around, one engineer discovered that a crazy arrangement of screws, nuts, C braces, and a washer performs passably as a linear bearing when a similarly crazy assembly is stuck onto the end of the channels. He worked on putting that together over the course of the meet, but it was never attached.
Our first match (which was also the first match of the night) was a total disaster. Our NXT battery was critically low because the other team needed the full battery (that we had been using) to pass software inspection. They never gave it back to us. Somehow, the simple autonomous program (that just drives forward from the ramp) vanished from the NXT, so we ran the complicated IR-involved one despite starting on the ramp. Since one of the drive motors' wires had gotten loose, the robot turned at the start, falling sideways off the ramp rather than driving down it. It did fully leave the ramp, so we got the points! Unfortunately, that fall knocked out the other motor's cable, rendering us inoperable. Our alliance partner was trying to move the tubes, but without much success. When they tried to climb the ramp, they fell off the side, but since the side of their robot that went off the ramp fell onto our disabled robot, they were fully off the floor and got the points.
It was about this time when we noticed that the real field layout was reversed from our practice field. This inconvenient fact rendered our IR-smart autonomous program entirely useless.
Despite that, we tried using the program in our second match. By sheer luck, it got really close to the kickstand, but missed it. We helped our alliance partner push tubes up the ramp, but our acrylic number plate got jostled loose. One corner fell to the floor and got jammed in the squishy mat, rendering us unable to move forward and only allowing very slow backward movement. We managed to park in the parking zone.
We used that same autonomous routine again to get down from the ramp, and it worked since we had repaired the motor connections. We tried to move the tubes to the ramp, but jammed them all into the corner and also got a big penalty for pushing one through the opposing parking zone. We did extract one tube and started to push it up the ramp. Our robot just barely got up off the floor with a push from the alliance team.
In the fourth round, we just used the stationary musical autonomous program. We pushed several tubes up the ramp and ended the game teetering on the brink with one tube and our robot partially off the flat part of the ramp. The allied team very carefully parked in the parking zone.
Our fifth and final match was a huge jam. The allied team instructed us to play defense, so we did our best to block the opposing alliance from accessing their tubes. A flood of balls and the kicked-down kickstand tripped up our robot, and we got stuck near the opposing tubes. An opposing robot tried to drive through the mess and got stuck on top of one of our front wheels. Neither of us were able to move for the rest of the match.
Our performance here was not great. I think we won only one of our five matches (the second one). We did make some progress on the linear slide system, but our capabilities were largely unchanged from the first meet.
Thursday, December 4, 2014
Robotics - Material of Champions
The robot was being tinkered with the entire three hours of this meeting, so I didn't get a chance to improve the autonomous program. Most of my time this meeting was spent watching the tinkering (trying to understand what was going on) and watching/tinkering with the 3D printer in the other room. A team member with experience operating 3D printers did some good work repairing the printer. After removing the extrusion head from the acetone bath, it was much cleaner and could actually extrude.
We then entered a period of trial-and-error with the printer bed height that took at least an hour. We had to tighten and loosen some hex screws at the corners of the glass bed to tune the height and angle, then wait for the bed and extruder to heat up again. Along the way, we also discovered a kink in the filament routing area that was stopping much of the plastic from entering the extrusion head. After all the adjustments, the printer can print our sheet of linear bearings, which should be finished in the morning. (It takes a while.)
The major feature that our robot needs before it can be useful is a lift to elevate the balls we take to the tubes. We also need a place to store the balls, so we had to put into production the cardboard box of prototypeness. It works, but looked really out of place in all the metal machinery. The aesthetics were soon repaired: a ramp from the ball intake belt to the storage box was built out of cardboard and attached with zip ties. That's some quality engineering right there.
To control the outflow of balls, we added a servo flap to that box. This is our first servo, so we had to find and mount a servo controller. The mounting was easy enough, but powering it was a challenge; the only viable mounting place was far away from the battery and on the opposite side of the robot as the Samantha module (which has to be the last device in the power chain). Since we didn't want to send cables all around and redo our existing ball of wires, we ended up jamming two wires into one socket to create parallel circuits.
There is a meet tomorrow! We'll test the servo flap controls and do some general polishing then.
We then entered a period of trial-and-error with the printer bed height that took at least an hour. We had to tighten and loosen some hex screws at the corners of the glass bed to tune the height and angle, then wait for the bed and extruder to heat up again. Along the way, we also discovered a kink in the filament routing area that was stopping much of the plastic from entering the extrusion head. After all the adjustments, the printer can print our sheet of linear bearings, which should be finished in the morning. (It takes a while.)
The major feature that our robot needs before it can be useful is a lift to elevate the balls we take to the tubes. We also need a place to store the balls, so we had to put into production the cardboard box of prototypeness. It works, but looked really out of place in all the metal machinery. The aesthetics were soon repaired: a ramp from the ball intake belt to the storage box was built out of cardboard and attached with zip ties. That's some quality engineering right there.
To control the outflow of balls, we added a servo flap to that box. This is our first servo, so we had to find and mount a servo controller. The mounting was easy enough, but powering it was a challenge; the only viable mounting place was far away from the battery and on the opposite side of the robot as the Samantha module (which has to be the last device in the power chain). Since we didn't want to send cables all around and redo our existing ball of wires, we ended up jamming two wires into one socket to create parallel circuits.
There is a meet tomorrow! We'll test the servo flap controls and do some general polishing then.
Wednesday, December 3, 2014
Robotics - 3D Debugging
At this extra-long robotics meeting, we spend most of the time tinkering with that 3D printer. With some clever use of Allen wrenches and screwdrivers, we disassembled the printing head and attempted to clean it. In doing so, we extracted a large chunk of failed extrusion stuck inside it. Several components require an acetone bath to become functional again, so we should have the printer online tomorrow!
The actual robot did receive some adjustments. Its wheel that fell off yesterday was reattached, as was the ball intake belt which fell apart. The divot-producing metal channel has been filed down so as to not damage the field.
I continued work on the autonomous, but the IR beacon's battery died and we didn't have a 9V battery laying around. We did eventually go down to the local hardware store and get one, but by then there was very little time left. I did some more testing of the routines we do have, and there is really no nice way to differentiate the center assembly positions from the current testing position.
The actual robot did receive some adjustments. Its wheel that fell off yesterday was reattached, as was the ball intake belt which fell apart. The divot-producing metal channel has been filed down so as to not damage the field.
I continued work on the autonomous, but the IR beacon's battery died and we didn't have a 9V battery laying around. We did eventually go down to the local hardware store and get one, but by then there was very little time left. I did some more testing of the routines we do have, and there is really no nice way to differentiate the center assembly positions from the current testing position.
Tuesday, December 2, 2014
Robotics - Continued Autonomous
At the previous meeting, we discovered that one small metal channel on the robot sticks down too far and causes problems when going down the ramp. (It actually made a divot in the floor mat!) We worked on filing it down, for lack of a better tool.
While others worked on that and tinkered with the partially-functioning 3D printer the AEA let us borrow, I continued working on the autonomous routine. It now does an excellent job of knocking down the kickstand in Position 3 thanks to better tuning of the turn time. I also started using the nicer HiTechnic IR Seeker 1200 drivers, so I can gain even deeper insight into the IR topology and make positional decisions based on that.
The program now checks whether the IR is in place for Position 3 before blindly going ahead and ramming a pole that might be there or might be a wall. I also added pathing and detection for Position 2. Unfortunately, the IR sensor occasionally produces the same value for Positions 3 and 2 from where I'm testing, so I may need to locate another testing spot. Both paths have been tested and work excellently. All that's left is to add pathing and detection for Position 1 and maybe rework the IR checking.
On Thursday, the good builders will both be there, so we can actually add hardware to the robot.
While others worked on that and tinkered with the partially-functioning 3D printer the AEA let us borrow, I continued working on the autonomous routine. It now does an excellent job of knocking down the kickstand in Position 3 thanks to better tuning of the turn time. I also started using the nicer HiTechnic IR Seeker 1200 drivers, so I can gain even deeper insight into the IR topology and make positional decisions based on that.
The program now checks whether the IR is in place for Position 3 before blindly going ahead and ramming a pole that might be there or might be a wall. I also added pathing and detection for Position 2. Unfortunately, the IR sensor occasionally produces the same value for Positions 3 and 2 from where I'm testing, so I may need to locate another testing spot. Both paths have been tested and work excellently. All that's left is to add pathing and detection for Position 1 and maybe rework the IR checking.
On Thursday, the good builders will both be there, so we can actually add hardware to the robot.
Monday, December 1, 2014
Robotics - Autonomous Time
No builders came to this robotics meeting, which made the extra length of it somewhat pointless. We started by trying to decide what to do for our linear bearings. The original idea was to 3D-print them, and we printed one, a prototype. It works perfectly, but no 3D printer owner in the area is willing to let us mass-produce them (we need at least 35 more) for free and soonish.
One option - which we started using as an experiment - is to use Sculpy, an interesting plastic-clay substance that is squishable until it's baked in an oven, at which point it becomes hard like plastic. The problems with this are that [1] we don't have enough Sculpy to make 35 more of these bearings and [2] we aren't nearly as accurate as a 3D printer, and accuracy is important (on the mm scale).
I started looking for online 3D print shops and discovered Shapeways. We determined that the cheapest material they'll use - sandstone (yes, you read that right, we can make robot parts out of sandstone) - will cost us $150 to print all the parts we need. If we use a decent material like plastic or metal, the price rapidly increases from $210.
We still haven't decided on our plan for that. While everybody else worked on Sculpy and our display board, I started working on our autonomous routine. At the first meet, all we could do was drive down from the ramp and play music. My current goal is to get it detecting the position of the kickstand and kicking it down.
After much testing, tweaking, and robotic destruction of the field, I got a routine starting in the parking zone, moving up to test for Position 3, spinning around, and utterly destroying that kickstand if it is in fact in Position 3. The infrared isn't hooked up to this program yet, but I did modify the tele-op program to play a tone indicating the value returned from the sensor (the angle of the emitter) at the press of a certain button. We did a bunch of driving around to verify that it is in fact working and help me figure out which infrared angles to use in the checks.
One option - which we started using as an experiment - is to use Sculpy, an interesting plastic-clay substance that is squishable until it's baked in an oven, at which point it becomes hard like plastic. The problems with this are that [1] we don't have enough Sculpy to make 35 more of these bearings and [2] we aren't nearly as accurate as a 3D printer, and accuracy is important (on the mm scale).
I started looking for online 3D print shops and discovered Shapeways. We determined that the cheapest material they'll use - sandstone (yes, you read that right, we can make robot parts out of sandstone) - will cost us $150 to print all the parts we need. If we use a decent material like plastic or metal, the price rapidly increases from $210.
We still haven't decided on our plan for that. While everybody else worked on Sculpy and our display board, I started working on our autonomous routine. At the first meet, all we could do was drive down from the ramp and play music. My current goal is to get it detecting the position of the kickstand and kicking it down.
After much testing, tweaking, and robotic destruction of the field, I got a routine starting in the parking zone, moving up to test for Position 3, spinning around, and utterly destroying that kickstand if it is in fact in Position 3. The infrared isn't hooked up to this program yet, but I did modify the tele-op program to play a tone indicating the value returned from the sensor (the angle of the emitter) at the press of a certain button. We did a bunch of driving around to verify that it is in fact working and help me figure out which infrared angles to use in the checks.
Subscribe to:
Posts (Atom)