Adventures with Lego Mindstorms: NXT
Thursday, November 8, 2007
You can download the new documentation package from their download section or directly from here. The documentation is split into five sections; Fundamentals, Movement, Sensing, Setup and Variables making access to the information that you need easy without having to search through a massive single document. It will also help teachers who are looking to save on printing costs for educators who will be printing multiple copies for the classroom.
I can now, with good conscience fully recommend this product to educators, students and experts alike. To quote Dr. Who: "Fantastic!"
Tuesday, February 20, 2007
Well, I was hoping to regale you all with tales of code churned out by the Megabyte, but allas.. it is not to be. There was code written and I was very excited to show you all, but when I came to work and inserted my USB drive, the entire thing was corrupted. Lost everything on it, including the code I had just created for this project, and the updated flowcharts as well. Not fun.
Well.. things happen and it looks like I will have a chance to improve on what I had written! In the mean time I have done some modifications on our Test Bed robot. Recently my LEGO Crane (8288) arrived and after completing the main model and then disassembling the entire thing I decided to give the wonderful tracks that come with the set a go. The results have been beyond my expectations! I would like to present to the world....
As you can see the big addition is the treads. However, the chassis design is such that you could also use my previous skid steer configuration easily. Both setups connect to the chassis in the same fashion using a long 15 hole Lift arm with the drive gear towards the back. The only change necessary would be to move the drive gear so that it meshes with the motor gear forward of it's current position.
This version of Mikey addresses some issues I was having with the overall sturdiness of the model. The back end of the robot has always been uncomfortably loose for my liking, and it is very hard to stiffen it up. You can see in this version of Mikey that I have added some stiffening bars to the back and a frame that comes down between the motors giving the rear of the drive assembly a place to connect. The loose rear end of the robot was causing some shaking during turns converting energy that could be used for movement into vibration. Stiffing up the rear end of the model has helped out considerably.
I have completed a LDraw file of the basic chassis and will be posting it up just as soon as I learn how to do so. Hopefully I will be able to make up some step-by-step building instructions as well. There are some things with the LDraw file to keep in mind!
- First off, I had some issues with connecting the treads to the chassis in MLCad. The entire drive assembly actually drops one hole from it's start position to give the gears room to mesh. In the LDraw file it appears that the rear axle connects one hole up from where it actually is supposed to go.
- The returns on the treads can be in any configuration you would like. There is one set up on in the LDraw file and another you can see in the pictures. Just fool around until you get it to all fit together.
- I have attached the weight from the crane set to the back of the chassis to give the robot some balance. The tSensor apparatus and the weight of the NXT cause the robot to be unbalance forward unless it is there. One solution would be to turn the NXT brick around so it faces the rear (like with Mike v2.0). It is a good solution if you don't have the weights, but would require a rethinking of the chassis.
Monday, February 19, 2007
Well it looks like I may have missed my deadline here. Luckily I don't have masses of angry readers posting comments, although that would be welcome indeed! Lots has happened since my last post and I figured I would take the time to give my rare, and endangered readers a quick update and some details on my current project.
I want to quickly go over BricxCC and NXC before I get into the project details. The first thing you will notice with BricxCC, as compared to RobotC is the lack of professional polish. This is very much an open source project, and unlike RobotC, it is designed to work with a variety of languages and Firmware. The choice is astonishing. There is a C# language for MS.net, Java and more! I haven't really looked at anything more then the availability of these languages as I am most comfortable programming in C/C++ and as NXC is available, I am unlikely to move to a completely different environment. The main choice for programming the NXT using BricxCC are NXC (Not eXactly C) and NBC (Next Byte Code). NBC has a structure very close to assembly language so if you are more comfortable in that environment it is an excellent alternative.
Both NBC and NXC are compiled with the NBC compiler, which has to be downloaded separately from BricxCC itself. Installation is simply unzipping a file into the root directory of the BricxCC application itself. One note here. NBC code should compile with the current release version of BricxCC, however, in order to use NXC code you will have to download and unzip the "test" version of the interface. You will need the standard release as well since the test version only contains changes and isn't the full application.
So far I am loving NXC. The reason, plain and simple, is that there is a programmers manual! I can't stress how necessary this is for any kind of programming language. That RobotC doesn't have a manual readily available makes it almost completely useless. Hopefully someone is working on getting this available for download ASAP. So until that happens I am almost certainly going to be sticking to NXC exclusively.
Da Code Boss! Da Code!
I want to give some background information here before I go on. I am not a developer, I am a systems administrator. As such, I have read thousands of lines of code, in various languages, in the course of my work. However, as a Systems Admin, it is very rare that I ever actually have to produce any from scratch. Back when I was still in school it was a totally different situation. Back then I was quite the coder. I loved the marathon sessions and can remember not eating, drinking, sleeping.. hell, it felt like we didn't even blink as we worked our way through esoteric problems, mostly just to see if we could. That was at least 16 years ago and pretty much the last time I could say that I coded anything from scratch. One of my biggest motivations in purchasing this set was to get down and dirty in the trenches and to see if I still have any foo at all left in these old bones. Oddly enough, it was like riding a bicycle. A quick look through the programmer's reference was enough and soon I was happily coding away almost like the old days. I really have to say, it felt GREAT!
The end goal of this project is to create and autonomous learning robot using evolutionary methods. At the moment I have a great deal of theory floating around in my head, but am still working out the details of implementation. So I decided to start out simple. In order to achieve my goal my robot will have to have an idea of where it is in the environment, what objects exist, their properties and location. As we don't want to have to program all this in, the robot has to have a method to gather this information from a starting point of knowing nothing. Also, as the instruments we are using to record this data are very inaccurate, and impossible to check, we have to build in a certain amount of fuzziness into the system and a way to resolve conflicts must be created. The end goal, and the mind numbing part of the whole project, is this conflict resolution. I am hoping to implement a Social Dissidence algorithm in order to resolve conflicts and a Q-based learning algorithm using weights to modify behavior. This is the road that I am embarking on. It will be a long journey and I fully admit that there are huge gaps in my knowledge and understanding that will have to be filled before I even know if it is possible or if we are speedily riding to the brink of a precipice.
However, there is a long way to go before we get into the more complex mathematical aspects of this endeavor. The first step in all of this is to have a system of reference. The easiest to implement is a simple Cartesian grid. This part of the programming is fairly straight forward and won't change even after learning is implemented. in order to define our grid, we first need a system of measurement, then we need to define the following;
Lastly, the robot has to return to a fixed point and return a (correct) location in the format of Location[x,y]. Our method of measurement is to use the GetOutput(OUT_B, RotationCount) function using the NXT rotation sensors to collect the data and using one rotation as our base unit of measure. Defining our grid is the easy part. The robot just moves forward from its start position (Location[0,0])until the Touch Sensor (tSensor) is activated. The number of rotations from Location[0,0] becomes our xMax. Turning around and repeating the process and subtracting xMax from the total rotations gives us xMin. The robot then returns to Location[0,0], turns 90 degrees, and repeats the process to return the values of yMax and yMin. Lastly the robot then returns to the centre, giving us our defined initial Location[0,0].
At this point we have to make some decisions as to how we will implement this logic. It is important to think about this now. While the initialization routine can be programmed in a linear fashion, our decisions at this point will effect the methodology of the entire project. Also, by insuring that the code generated is written in such a way that it is both generic and portable, I can start creating my own library of functions which I can then snap together just like building a LEGO set.
So, how do we go about doing this. First off I have decided to use a State based programming methodology. Each of the various tasks the robot performs is assigned a state with 0 set as NO STATE. As each function is executed, it changes the State flag and sets PreviousState == State. This way we can modify the behavior of the robot depending on what it was last doing. So far our states are as follows;
- 0 - No State
- 1 - Collision
- 2 - Initialization
This requires several different tasks with different functions. First, we need a State Monitor to watch the state variable and call the functions based on that variable. We also need a Sensor Monitor to watch for our tSensor hit and to record values for our Light Sensor (lSensor) which watches to see if the robot is on carpet or hard flooring so that it can modify it's turning depending on what kind of surface it is traveling over. Environmental effects, like a tSensor hit, causes the state to change but don't initiate any other action. Instead the State Monitor takes over and initiates an appropriate response. We will also need a function to monitor the location of the robot, but that comes later and is unnecessary until the Initialization sequence is complete. Object handling and Avoidance are also considerations that we can ignore for now.
While this may sound complex, it actually is quite simple and drastically reduces having to code redundant functionality. Lets look at our Initialization sequence. When turned on, our Robot will be in state 0. The state manager checks the previous state, sees that it is also 0. This will only happen before any action has been taken on the part of the robot. The State Manger then changes the robot's state to 2 and starts the Initialization sequence and sets PreviousState == 0. As the robot moves forward to define Xmax we are using our tSesnor to tell us when to stop. When hit, the Sensor Monitor would set PreviousState == State (in this case 2 and 1 respectively) and the State Monitor then pauses the initialization sequence and calls for the code for tSensorHit to be executed. This is simply to back the robot up enough that it can turn around with out hitting anything and is common to any tSensor event. State == PreviousState (back to 2, initialization) and PreviousState is set to 1 to show that the last action was a collision. The state manager then returns control to our initialization sequence and away our robot goes having determined xMax.
I like to use flow charts to visualize the logic before I write the code and here (When I figure out how to post PDF files) is the rough draft of the logic for this initialization sequence. I haven't yet defined the logic for the State Manager, but I am hoping that this will give you some idea of the logic we are trying to implement. Flow charts are an excellent tool to help visualize the logic, and let me see how changes in one subsystem will affect the rest of the program, without having to modify code. As I write the code itself, and learn the functions available to me in NXC it requires some rethinking of the logic. You can see this process in the modifications I have made to the REVmotorLR and DefineXmax functions as compared to FWDmotorLR and DefineYmax.
Now for elbow grease!
So now I have the logic worked out it is a matter rolling up my sleeves and writing the code. Hopefully that won't take long and will get faster as time goes on. I am still feeling my way around the language and my printed copy of the programmer's manual is getting rather worn and dog eared by now. One problem that I know I will run into and I have to solve before the robot can do anything is the question of motor control. In NBC there is a function that takes over motor control for a thread expressly and then releases it once done in a cascading manner. I am sure that there is a counterpart in NXC, but I haven't found it yet. Gaining and releasing control gracefully is going to be critical.
So that is it for now! I have ungraded Mikey so that he has tracks now. I have also done some modifications on the chassis to make him more sturdy. More pics and hopefully some building instructions coming up soon! Stay tuned!
Wednesday, February 14, 2007
Stay tuned to this space for a description of my current project and come along for a ride as we explore programming an autonomous learning robot!
Sunday, February 4, 2007
Choice choice choice!
The programming options for the NXT are wide and bewildering, and unfortunately at this point, somewhat immature. This isn't much of a surprise for a product that has been out less then a year. Indeed the variety of options is a good indication of the potential for the NXT as a development platform. There seems to be two main classes of programming interfaces. The first is a representative system that uses icons and flow chart arrows to control program flow. Both NXT-G and Microsoft's Robotics Studio use this method of programming. While I am sure that this means is effective to program most functionality, this isn't the first time I have seen programming software try this interface method and without exception they have all failed. One of the biggest reasons for this failure has been the lack of flexibility that these programs offer. They are excellent for programming physical actions, have a very fast and shallow learning curve but break down once you try and apply advanced mathematics, logic or formalization.
Compiled vs. Interpretive Programming Languages
This leaves the more traditional method of text based coding. Here is an example written in RobotC to make a robot move forward;
// move robot forward
task main ()
motor[motorA] = 100; // Activate Motor A and provide 100% power to it
motor[motorb] = 100; // Activate Motor B and provide 100% power to it
wait1msec(1000); // Wait 1000 milliseconds.
// Program ends and motors shut off
Interpretative systems are well known and popular in the industry. The JAVA programming language is an interpretative system. Microsoft uses VM and interpretative systems in their latest programming languages.
An interpretative VM enables a robust solution that can be more defensively oriented against end user programming errors. When programming in native instructions, it’s relatively easy to corrupt a program or memory. In a VM environment, it’s possible to check and validate instructions to (usually) ensure that they don’t provide unexpected actions – e.g. ensuring memory accesses are to valid locations, better checking for overwrites, etc.
The NXT firmware program is over 100K bytes in size. In RobotC, you only have to download a small user program (typically 500 bytes or less in size) instead of a complete 100K firmware operating system. Download times are significantly reduced – seconds vs a minute or so.
We believe the existing NXT device drivers and the surrounding “Operating System” best fit an interpretative environment. More details can be provided once the NXT firmware is open-sourced.
I don't really accept this logic. The advantages of Interpretive systems come at the price of performance, size and memory usage. Java is an excellent example of this as it is, to say the least, a hog. I won't even go into Microsoft languages. Unfortunately, it would seem, that the more you know about MS products and languages, the less you know about how things actually work. MS goes a long way to hide or obfuscate these details in their projects and programming applications for Intellectual Property reasons. This is one of the main "advantages" of interpretive systems from Microsoft's view point. Programmers enter in commands that are interpreted into system calls. The programmer doesn't have to have any detailed knowledge of how the system works, just know the commands to give a certain result. For detail into Microsoft's reasons for switching to interpretive languages you really have to start to look at .NET, its methodology and the reasons it hasn't been accepted as an industry standard. Automated handling of variable types, and memory management are another advantage of interpretive systems.
In defence interpretive programming systems the logic is often given that modern computers have so much RAM and processor speed that the extra required to run the interpreter and load the code is a moot point. However, this argument breaks down when you apply it to the NXT brick. Lets take a look at the processor and memory specifications of the Brick;
- - 256 KB FLASH
- - 64 KB RAM
- - 48 MHz
- - 4 KB FLASH
- - 512 Byte RAM
- - 8 MHz
As you can see, we aren't exactly working with a beefy system with a lot of RAM here. While this is more then sufficient for the application, obviously with only 256KB of storage and 64KB of RAM, program size and memory performance is critical. Especially with interpretive systems as the interpreter must be loaded into RAM along with the code itself, rather then just a, much smaller, compiled binary file.
RobotC isn't just for NXT and also will be providing support for the VEX platform as well as a complete 18 week educational curriculum geared towards high school and middle school students. This is an ambitious project and until I find a compiled solution, it is the product that I have the greatest expectations for. The syntax closely follows C programming and as such I feel it is a better educational product then the interfaces using Windows Icons and Mouse Pointing. As this is a commercial product my standards reflect this and I expect this product to be ready for prime time with complete documentation before it is offered for commercial sale.
In their FAQ the creators of RobotC have made claims that their interpretive system makes impressive speed gains, especially when compared to compiled code which are impressive to say the least.
I am not sure if this is a comparison to compiled code running on the LEGO Firmware or a overall speed increase. I emailed one of the developers for confirmation but haven't yet received a response. One thing is for certain. The RobotC firmware enables the use of float variables and allows for much more mathematical flexibility. That alone makes it superior to the standard offering by LEGO.
Here I must say we come to what has to be the shining jewel of RobotC. More then even the slick interface the willingness to help that I encountered from the developers was very impressive. When I filed Bug Reports they quickly answered with solutions to try. Even when I had already posted a fix they filed notes to help better understand the issue I had. I do have some serious concerns with the documentation, but if the development team can keep that customer focused approach, I think it can be more than overcome.
The installation of RobotC was not a smooth experience for me, which for some reason seems to be a constant property so far with the Mindstorms NXT product. The experience was very similar what happened when I updated my firmware using the NXT-G. I have a feeling that the issue doesn't reside with RobotC but rather with the NXT brick itself.
Installation of this product is a two step procedure that involves upgrading the firmware on the NXT device to the custom firmware provided by RobotC. There are very good instructions available on the RobotC website to help with most situations. Unfortunately it was not fated for me to have an uneventful install. Following the instructions I started the firmware update process from within the RobotC interface and pressed the button to start. Much like when I was upgrading the standard firmware my brick just started clicking softly; however, this time, on the screen in front of me was the "Found New Hardware Wizard". For those of you who read my first Blog post you will recall that when I was updating standard firmware the computer wouldn't recognize the brick at all. So I thought to myself "At least we get THAT far!". I wasn't too scared, having been through this before so I reset the brick by pressing the reset for a good ten seconds and plugged the USB cable back into the brick.
This is when my difficulties really began. Again the computer recognized the NXT Brick as a new device, and again couldn't find drivers for it. I scoured the RobotC website for drivers, looked in the program folder, everything I could think of with no luck. By the time I started looking for a method to contact the developers I was getting a tad upset and very worried that I now had a seriously FUBARed brick. After a somewhat vitriolic posting on the Bug report site I did a complete uninstall/reinstall of everything NXT related and that managed to fix the problem and let me continue on with a regular setup.
One of the strongest features of RobotC is their compiler interface. Of course one can always program code in a text editor; however, using a interface can make things a great deal easier. RobotC has taken things one step father along these lines and added a side bar containing common coding functions that can be dragged into the main editing window giving you a easy template to fill out, letting you not worry so much about syntax.
One of the nice things about RobotC is that it was written especially for NXT. The entire product has a very cohesive feel and it is nice to have all the functionality working. RobotC also has a very well thought out sensor polling function that allows you to easily see levels and configurations of both sensors and motors in real time. Throughout there is the feeling of a professional coding environment.
There are a few flies in the ointment; however, they are minor. The editing window can only handle one open document at a time. This is somewhat annoying when you are trying take code segments from one file to another or compare code in two different files. I am also not a great fan of the sensor setup dialogs as they tend to dump a lot of useless text comments along with the code. In the end it is usually easier to just type in the sensor set-up command yourself like this;
Beyond those minor points using the interface has been a real joy. I am sure that it will only get better as this product matures.
My Gold Standard for documentation for any project is the OpenBSD FAQ. This is the first stop for anyone needing to know how to do something in OBSD and, despite its fearsome reputation, is usable by both experts and beginners alike. More importantly, no change that is visible to the user, in any way, is implemented before complete documentation is created and available. It is a philosophy I appreciate.
In this regard I feel that the developers have jumped the gun and offered the product for sale before it was ready. You can purchase RobotC from LEGO Education for $49, At the time of this article the product is listed as Out Of Stock, but as it is available for order I am not banging on about nothing.
The RobotC documentation is an attempt to do more then just provide a manual for their product. They endeavor to provide a complete 18 week course curriculum. This course covers introductory programming as well as the specific commands needed to work with the NXT and eventually VEX platforms. The course assumes that the student starts with no programming knowledge and works to build up from there. It is presented as a series of videos, PowerPoint presentations and worksheets, all of which are extremely professionally packaged in a manner that can only be described as "slick". They are clearly presented and easy to follow, even if I did find that some segments would be better as a single video rather then several separate smaller presentations. The whole thing fell down around PowerPoint #5 with a simple IF statement. I copied and pasted a program example from the presentation slide and it refused to compile at all, even after I had corrected the obvious syntax errors.
I filled another bug report and, with blinding speed, not only was I rewarded with a response, but an entire site change! I can't comment on the current documentation, as I haven't yet had a chance to look it over yet. One, somewhat ominous, sign is a large BETA mouse-over on the Software Training section on the site and the total absence of a section marked Documentation. One very obvious omission in basic documentation is any kind of manual at all. There is an excellent start on course materials for beginners, but these haven't even progressed as far as structured programming, leaving an experienced teacher or programmer wondering what syntax is used for more advanced programming structures. This is only partially made up for by a reasonable selection of sample code that comes with the application and there is a user Wiki where the community can help out.
The documentation of the RobotC project is its real downfall. The application is professional and well polished but its documentation resources have the feeling of a poorly organized Open Source attempt. Amazingly slick at one moment, incomplete and inaccurate at another. Development to overcome these downfalls is on-going and has great potential; however, as this product is sitting on the shelves as we speak, it falls far short of the expectations appropriate to a commercial release. The lack of a manual combined with the Beta state of the course materials unfortunately cripple a otherwise excellent product. Without the manual, teachers can't create material to cover the holes not yet documented by the RobotC team, nor would they be able to correct problems with the code examples handed out to the students except by deconstructing the example programs. This may be all well and good for the single, highly technical user, but hardly a good use of time for a teacher who has students to think about. Eventually this will, undoubtedly, be the premiere interface for teachers who wish to have a more flexible environment then the NXT-G or Microsoft Robotics interfaces but until the documentation at least approaches the promise of the interface I would recommend sticking with the demo versions and keeping your wallet in your back pocket.
Wednesday, January 31, 2007
Ordering the Product
First off, let me say that I really love this site. It is well organized, up to date and offers a bewildering array of products from the standard NXT sensors right up to highly accurate scientific sensors based on the IC2 interface. Their selection of individual parts is amazing and the prices are very acceptable. They have a "wish list" function so you can cue up purchases. All-in-all a wonderful site; however, the design, the logo and the products all imply that LEGO Education is a branch of LEGO itself. It is not, and this should be indicated clearly when ordering.
The order process seemed to go very smoothly. There was one note that my address would need to be confirmed by LEGO Education before my order could be sent, and I was offered the option of pressing continue in order to start this process. As a Canadian and ordering from a US site, this isn't a strange experience for me. More then a few sites require some sort of confirmation before sending products across international borders. However, after about a half hour I received an order confirmation which I have pasted below;
Thanks for your order from LEGO Education.
A brief summary of your order is below.
Please feel free to contact us if you have any questions.
Order ID: 166916
Merchandise Total: $109.00
Local Tax: $0.00
State/Province Tax: $0.00
Country Tax: $0.00
Order Total: $117.72
Gift Certificate: $0.00
Grand Total: $117.72
These products will be shipped to the above address:
Product Name: Education Resource Set
Attributes (if any):
2. Product ID: W979798
Product Name: NXT Rechargeable Battery
Attributes (if any):
Not as advertised
Once I had received this confirmation I figured I was set to go. Boy was I mistaken! I placed my order on Friday and received my confirmation Friday evening. Upon reading the confirmation it certainly seems like my card had been charged and that the order was on it's way. On Monday I went back to LEGO Education and checked my order and was quite surprised to see that it was still in Pending status. Confused as to why it was taking so long to process my order, and suspecting that it might be waiting for the Resource Set to be back in stock I phoned up the number listed on the website and spoke to one of the customer reps there. It was then, and ONLY then that I was informed that LEGO Education doesn't ship to Canada. Of course my question was, "Why, then, did you confirm my order?".
Eventually I was connected to a manager who informed me that LEGO Education has a distributor in Canada that all orders have to go through. I was also directed to a wizard, buried deep in their FAQ that supposedly informs customers of this fact. Of course nothing during the order process itself tells you this and the order confirmation leads you to believe that your order has been accepted. Finally I was more then a little annoyed that the only way I found out about this little quirk was to call LEGO Education directly myself. One would think that an email would be sent out, or at least the order status would be changed on their website. None of this happened. The manager directed me to Spectrum Education their Canadian Distributor. As you can see by the website, it wasn't easy to even find any LEGO products. So I downloaded their 400+ page PDF catalog and searched it. Much to my complete surprise I didn't find any mention of Mindstorms NXT and instead was presented with a catalog of RCX products presented like they were new.
The Run Around
By now I was feeling like I had been given a run around of epic proportions so back I went to LEGO Education. I was able to speak to the same manager which tells me that they have a ticketing system and excellent support for customers, normally. The situation as it stood was totally unacceptable. As a consumer, the distribution arrangements between LEGO Education and Spectrum Education are none of my concern. Nor does a wizard buried four pages in mitigate the situation. The entire issue reminds me of when Best Buy offered video cards on their website far below market value due to a typo on their web page. At first they refused to honor their price, but were eventually forced to honor the deal they advertised. The situation here is the same. I was offered a product, purchased a product, received confirmation of that purchase.. I would expect that my product would be shipped, or at least I would be contacted in the event of any problems. None of this occurred so I demanded that LEGO Education honor their offer or I would be taking my case directly to LEGO. Happily they honored their agreement, processed my order and it will be shipped to me as soon as The Resource Kit again is in stock.
I have to admit this I find this entire situation baffling. I don't see how this agreement benefits either LEGO Education or Spectrum Education. I would have expected my order to be processed by LEGO Education and then passed on to Spectrum for the product to be sent out. After all, the more product that Spectrum sells, the more money LEGO Education makes. Especially considering that Spectrum doesn't have online shopping on their site and they carry a far larger selection then just LEGO.
Before anyone takes this review as a total bashing of LEGO Education I would like to say that their customer service was excellent and the amount of people who have experienced this problem is very small. From what I was told I was the first customer to encounter this kind of problem. From my point of view this is a good thing as it gives them a chance to fix the issue before thousands have this problem. After all, Canada isn't exactly Bulgaria (where they ship to without issue I might add) and for every person who complains, there are 10 who didn't. Also as this site is made up to look like it is part of LEGO International, a poor experience with them reflects badly on LEGO International regardless of the actual situation. Perception IS reality. This issue shouldn't effect US and most international customers at all and the quality of the site is a step above most online shopping stores that I have seen. I have to commend them on insuring that I was satisfied and that they worked very hard to resolve my issue. If they fix the problem with ordering and modify their distribution agreements to come into the 21 century I would have no problem recommending this site to any Canadian client. I would not however recommend Spectrum. Their website is extremely slow, even sitting at the head end of an ISP as I am currently. Many of their catalog pages won't come up, their catalog is hopelessly out of date.
The problem was frustrating but there was a good resolution. Problems will always occur and issues will always arrise. The mark of a excellent company is how they deal with these issue and the resolutions they come up with. In this case I am very satisfied on that note.
Sunday, January 28, 2007
I would LOVE to post pictures, links and event details, maybe even drop in to see what is happening; however, this event has NO web presence. A search on Google brings up no links for Robotic Competitions more recent than 2002 in Edmonton. There is no story on CBC.ca, no links from the University Website nothing, apparently, anywhere. Of course I have many, many links to the Mobile Robotics Competition that happened back in 2002, but that hardly helps.
Nice work guys! I would love to support you, unfortunately you have made it impossible.
Good luck with that!