TrackingHardware
Software
Mega PlanEtc. |
Main /
BrainstemThe Brainstem can be controlled in three basic ways:
We take advantage of all three of these options. Using I2C or Serial, the Gumstix will query the Brainstem's current sensor values or command it to move its servos. Additionally we download a TEA program onto the Brainstem which maintains a current count of incoming encoder values which we can query and reset from the Gumstix. Provided Acroname SoftwareAll you need to know about Brainstem can be found on Acroname's Brainstem reference page. Additionally, the following software utilities are available from Acroname for Windows, WinCE, MacOS X, PalmOS and Linux. The GP application provided in Acroname's Brainstem software distribution allows the user to view readings from the various inputs such as analog output, digital outputs, and servo readings. With the sliders the GP GUI provides, the user can also adjust servo inputs and other related servo configuration such as range, etc. Whatever changes are made in the GP GUI session with the Brainstem can ultimately be saved to the Brainstem permanently by clicking the Commit to EEPROM button in the GP GUI. Playing with the GP GUI and your robot's servos and sensors can help you get an understanding of what kind of values you should be sending or receiving from them. The Console is a text-based GUI that allows the user to send Brainstem commands, compile TEA programs, test TEA programs, and make permanent changes to the Brainstem EEPROM. From the Console the user can send sequences of numbers which represent commands to the Brainstem. The user can compile TEA programs, with the steep command, from the Console into native assembly language for the Brainstem microprocessor. If there are any errors in the TEA code, the Brainstem console will report them to the user via the GUI. The Console will print to the screen whatever commands are sent to it from the Brainstem. When running, this can include debug statements placed in the TEA program. A TEA program is essentially a C program that can make TEA Language calls on the Brainstem. A TEA program may also include assembly language for the Brainstem, known as TEAvm, to perform absolute lowest level instructions on the Brainstem. To compile a TEA program from the Console the user must place a copy of the TEA program in the aUser directory of the installed Brainstem software distribution, preferably with an extension of .tea. Then start up the console and type in steep <filename> which assumes a .tea extension to the program. If there are any errors during the compilation phase they will be reported on the Console GUI. The user can then correct the errors and try compiling again. If the compilation is successful the resulting object code to be eventually loaded and launched on the Brainstem will be placed in the aObject directory of the installed Brainstem software distribution with an extension of .cup. After compiling, a user can load compiled TEA programs into job slots on the Brainstem processor and then launch those programs and even pass in simple command line arguments to the programs when launching from the GUI. Setting up SoftwareYou set up the Console and GP programs by placing in their respective directories a filed called
where serialDevice is your device (like 'COM1'). Note: If you are using the popular Keyspan USB Serial Interface, it installs as follows:
Note: To do the Java drivers, you need Sun's javax.comm library installed. OS X binaries for this can be found here. Windows The Windows (win32) GP Program and Console works adequately. The biggest problem you're likely to encounter is COM port identification. Since the GP console and the demo look for COM1 by default they give you message saying unknown serial port if you're only connection is COM2. Check out your hardware configuration for this. Another problem is that the java comm api had instructions for where to put the comm.jar file and javax.comm.properties, but this wasn't enough. It worked for us after copying these files to lib and ext files in the java directory. My machine needed the files in 4 places. After these issues got worked out everything worked fine. OS X On OS X, there's a bug in Acroname's Console and GP programs. They're looking for a library called IO.framework and expect it to be in a directory called
Another workaround for this bug is to place the *.framework directories in
Linux There is no linux build of the GP application. However, the win32 version runs under wine by
mapping
The only catch is that you have to turn the robot on first, otherwise the GP may not get a
link. The console application works fine under wine as well with the same
On Linux, it's slightly more complicated than on OS X to get your programs compiled and linking properly with the brainstem C dev kit. Here's a quick guide on how to set your projects up so that they'll compile correctly.
cd brainstem/ # create folders for your project mkdir projects mkdir projects/programname # note: this last folder *must* be named aUnix mkdir projects/programname/aUnix Create your program This file must be named /* brainstem/projects/programname/aUnix/unix_programname.c Hello World */ #include "aStem.h" /* stem library header */ #include "aServo.h" /* servo control routines */ #include "aDigital.h" /* digital I/O routines */ #include "aAnalog.h" int main(int argc, char* argv[]) { printf("Hello World!\n"); return 0; } Create the precompiler headers. Yes, you MUST do this. Again, replace "programname" with your program name. Here are the examples: /* brainstem/projects/programname/aUnix/unix_programname_pfxd.h */ #define aDEBUG #define aUNIX /* brainstem/projects/programname/aUnix/unix_programname_pfx.h */ #define aUNIX Create your makefile now. NOTE: Again, you have to replace all places where it says "programname" with your program name, including the place where it says unix_programname.c. You also have to modify other variables in here for your own ARCH / CC / SHELL locations. # brainstem/projects/programname/makefile SHELL=/bin/sh CC=arm-linux-gcc ARCH=ARM PLATFORM=Linux ROOT = ../../ PROGNAME = programname INCLUDES = -IaCommon -IaUnix -I../../aCommon -I../../aUnix \ You can now just type: make Running your program. The first thing you'll wonder the first time you compile is a large stream of errors, because it can't find a bunch of stuff. No worries, the make process should make the stuff it needs for later. It should compile on subsequent runs without error. The second thing you will wonder is... "where's my program?" The answer is in: brainstem/aRelease/aUnix/i686. You have to run your program like this: ./run programname Software LibrariesAcroname provides four main software libraries for use with the Brainstem: TEA and TEAVM TEA is essentially C. TEA is the language that Acroname provides a compiler for, called steep, to change TEA code into runnable code on the Brainstem. Similar to C, in TEA an asm block contains assembly language commands to be compiled into the runnable code and in this case Acroname calls the assembly used for the Brainstem, TEAvm. TEAvm is just the set of processor level instructions and parameters the Brainstem processor supports. Writing code in TEAvm is how to code at the lowest level on the Brainstem. One thing to keep in mind about compiled TEA code with or without TEAvm assembly in it is that the maximum space a program has to run on the Brainstem is 1K per program. Several programs can be run at the same time on the Brainstem but the 1K limitation holds for each individual process. Obviously, complicated code will not fit on the Brainstem so use TEA programs for low level chores that make sense to run on the Brainstem such as the wheel encoding that was used in this project. The good news is the steep compiler will tell you how big the image is on a successful compile. However, don't push it past 512 bytes (0.5Kb) if it can be helped because this does not include space for the stack each program needs to run on the Brainstem with. Java library The java distribution provided should be installed in the aJava directory in the home of wherever the user installs the Brainstem software. acroname.jar is the main jar file provided by Acroname which encapsulates sending and receiving various commands to the Brainstem from a remote Java application located on another processor such as a client PC, Mac, or embedded processor such as the Gumstix. There is a java file named gp_example.java provided by Acroname which demonstrates using the acroname.jar API in Java. Also, Acroname provides the source code to their acroname.jar library in the aJava/acroname folder so you can both modify their library code and more importantly understand how to communicate with the Brainstem using the Java Serial classes. C library similar to the Java library but for the C language and again this allows remote C programs located on another processor to send and receive commands from the Brainstem. Changing the I2C Address on the BrainstemIf you're going to command the Brainstem via I2C from the Gumstix rather than via the Serial port, you'll need to change the Brainstem's I2C address because it conflicts with the Gumstix's address. I2C addresses are 7 bits. The Brainstem stores these in the upper 7 bits of a byte, which is why they only allow even addresses. To determine the real I2C bus address, divide the Brainstem address by 2. The default address is 2, which corresponds to a bus address of 1. That's the same address which is used by the Gumstix, so we're going to change it on the Brainstem. Power up the Brainstem (by connecting it to the battery or by plugging in a 5-7V power supply). Connect your computer to the Brainstem over its serial port. Launch the Brainstem Console application (you can get this from Acroname.
Turn the power to the Brainstem off, and then back on again. Verify that the address is 4 by typing 173 in the Console application. To use the serial port again you will need to switch the Brainstem's address back to normal so its on-board serial port router can find it again. The sequence of commands to do this is:
Quadrature Wheel Encoder using TEAThe Wheel watcher software uses quadrature encoding to determine the number of gradations your wheel has passed, and thus, your wheel speed. Quadrature Encoding means the watcher software can determine your direction (forward of backward) in addition to velocity. The quadAandB program assume that left and right counters will be stored in scratch pads 28 and 30 respectively with reset pads at 24 and 26 respectively. It also assumes that channel A and B for the left encoder will be plugged into digital ports 0 and 1 respectively, and that the channel A and B for the right encoder will be plugged into digital ports 2 and 3 respectively. If for some reason, you do need to change these constants you can modify the #define's at the top of quadAandB.tea, recompile in the console with the steep command mentioned above and it will use the new constants. The resolution provided by this scheme is 128 per revolution. Since the quad encoder software is looking at both channel A and B it can also determine the direction the wheel has rotated and this is indicated by the counter incrementing or decrementing. Also, the range of the scratch pads allows for a range between -16384 and 16383 I believe. Therefore, if users of this software do not keep an eye on the current counts they can overflow or underflow so it is important to reset the counters if necessary. I tested this with the servo going full blast in one direction and it lasted a little over 2 minutes for it to encounter this scenario. Encoder Code InstallationThe code is available for download here and is listed further down in this page for your perusal. There are to two required programs and a test program:
To install and run the software, do the following:
The quadAandB program is now running and keeping counts of how far the wheel(s) turn. The test application can verify that the installation was successful and the wheel watcher is running. The test program checks the right wheel and assumes the A and B channels from your right wheel and plugged into digital port 2 and 3, respectively. To run this test program do the following:
After you have the quad encoding TEA programs loaded you can do the following to make them bootstrap programs, which means they will automatically start the next time we reset the Brainstem. Just type these two lines at the Console after you have loaded the TEA programs onto the Brainstem: 2 18 15 0 2 19 If you turn the brainstem off, the next time you turn it back on the Brainstem will launch the launch program which will kick off the encoder and it will be running immediately. You can test this again by loading and launching the test_quadAandB program and seeing the counters and reset working correctly. The Encoder Code Listings(For your reading enjoyment. A small portion of the code is copyright by Acroname and is distributed with their permission.) quadAandB.tea#include <aMulti.tea> #define AWWDEFS_LMO_CHA 0 #define AWWDEFS_LMO_CHB 1 #define AWWDEFS_RMO_CHA 2 #define AWWDEFS_RMO_CHB 3 #define AWWDEFS_QUADCT_AB 2 #define AWWDEFS_B_AND_DIR 1 #define AWWDEFS_A_AND_B 0 #define AWWDEFS_LMO_ENC_RESET 24 #define AWWDEFS_LMO_ENC 28 #define AWWDEFS_RMO_ENC_RESET 26 #define AWWDEFS_RMO_ENC 30 #define AWWDEFS_LMO_DIR 1 #define AWWDEFS_RMO_DIR 3 /* quad count lookup table */ char b0000 = 0; char b0001 = -1; char b0010 = 1; char b0011 = 0; char b0100 = 1; char b0101 = 0; char b0110 = 0; char b0111 = -1; char b1000 = -1; char b1001 = 0; char b1010 = 0; char b1011 = 1; char b1100 = 0; char b1101 = 1; char b1110 = -1; char b1111 = 0; void main(char callingProc) { char preR = 0; char preL = 0; char tempR = 0; char tempL = 0; aMulti_Wait(); while (1) { if(aPad_ReadInt(AWWDEFS_LMO_ENC_RESET) == 1) { aPad_WriteInt(AWWDEFS_LMO_ENC, 0); aPad_WriteInt(AWWDEFS_LMO_ENC_RESET, 0); } /* check left encoder */ asm { pushmb aPortDigital + AWWDEFS_LMO_CHA * aPortDigitalBlockSize + aOffsetDigitalIO pushmb aPortDigital + AWWDEFS_LMO_CHB * aPortDigitalBlockSize + aOffsetDigitalIO pushlb 1 rlb orb /* s = ((B << 1) | A), offset = 1 */ pushsb 1 popbs 2 /* tempL = s */ pushlb 2 rlb /* s <<= 2 */ pushsb 4 orb /* s |= preL */ convbs incs 2 /* offset to start of array */ pushsbax convbs pushms aPortScratch + AWWDEFS_LMO_ENC adds popsm aPortScratch + AWWDEFS_LMO_ENC pushsb 1 popbs 3 /* preL = s */ } /* check right encoder */ if(aPad_ReadInt(AWWDEFS_RMO_ENC_RESET) == 1) { aPad_WriteInt(AWWDEFS_RMO_ENC, 0); aPad_WriteInt(AWWDEFS_RMO_ENC_RESET, 0); } asm { pushmb aPortDigital + AWWDEFS_RMO_CHA * aPortDigitalBlockSize + aOffsetDigitalIO pushmb aPortDigital + AWWDEFS_RMO_CHB * aPortDigitalBlockSize + aOffsetDigitalIO pushlb 1 rlb orb /* s = ((B << 1) | A), offset = 1 */ pushsb 1 popbs 3 /* tempR = s */ pushlb 2 rlb /* s <<= 2 */ pushsb 5 orb /* s |= preR */ convbs incs 2 /* offset to start of array */ pushsbax convbs pushms aPortScratch + AWWDEFS_RMO_ENC adds popsm aPortScratch + AWWDEFS_RMO_ENC pushsb 2 popbs 4 /* preR = s */ } } } launch_quadAandB.tea/* Launches the wheel watcher encoder quad A and B TEA program */ #include <aMulti.tea> void main() { /* launch wheel watcher encoder TEA program */ /* (program 1 in process slot 3) */ aMulti_Spawn(1,3); aMulti_Signal(3, 0); } test_quadAandB.tea#include <aCore.tea> #include <aMulti.tea> #include <aPrint.tea> #include <aServo.tea> #include <aWWDefs.tea> void main() { /* launch Wheel Watcher task */ /* (program 1 in process slot 3) */ int j=0; int Iterations = 0; /* aMulti_Spawn(1,3); aMulti_Signal(3,AWWDEFS_QUADCT_AB); */ /* start servo stop position is 122 for now*/ aServo_SetAbsolute(3, (unsigned char)122); /* show encoder counts */ while (1) { Iterations++; aPrint_IntDec(aPad_ReadInt(AWWDEFS_RMO_ENC)); aPrint_Char(','); aPrint_IntDec(Iterations); aPrint_Char('\n'); aCore_Sleep(3000); if (Iterations == 29) aPad_WriteInt(26, 1); else if (Iterations == 41) aPad_WriteInt(26, 1); else if (Iterations == 49) aServo_SetAbsolute(3, (unsigned char) 135); else if (Iterations == 58) aPad_WriteInt(26, 1); else if (Iterations == 65) aServo_SetAbsolute(3, (unsigned char) 250); else if(Iterations == 92) aPad_WriteInt(26, 1); else if (Iterations == 189) break; } aServo_SetAbsolute(3, (unsigned char) 135); } |