LEGO Unimog 8110 Pics

I’m still working on my camera setup – but these are decent closeups;

Click Pic to go to my Picasa Album

Posted in Lego | Leave a comment

NXT Teleop Rover – Android source and LDD file

Purpose

I recently did a project that allows you to drive a LEGO Robot with a webcam on it, in my case I used an Android phone camera. You drive the Robot remotely using an Android tablet, using tilt, and watching its webcam. I had done a similar project several years back, and wanted to update it, using newer technology. In the previous version I had written my own ‘webcam’ software and implemented it as a http web server. There are now good stand alone webcam packages available for Android phones (such as IP WebCam), and probably others as well, and I wanted to use them as opposed to my own somewhat hacked code.


I was able to use code from the LEGO MINDdroid application for the low level bluetooth communications to the LEGO NXT. This saved a ton of time, as they make the source available and have already done a lot of the hard work. As an experienced developer, I knew what I wanted to add, and this is where I struggled a bit, finding good working examples of what I wanted to do. I say experienced, but I was not experienced in Android development. At one point I wanted to draw my own control to display the joystick (tilt) position. The only thing I found was a full screen application with a particle system that displayed many three dimensional balls. I needed 5 lines of code, it had 2000. So while it may have the needed information, it was overkill as an example.
With that in mind, I present the results of my project, both as Android source code with some explanations, and the LEGO Digital Designer file to make your own robot from. Thanks again to LEGO for the NXT platform in general and making the MINDdroid source available. Thanks to Douglas Taylor, rChordata for his DiamondPoint algorithm (used and distributed with permission), the best differential drive algorithm I have ever seen.

The files

NXTTeleop

I’m a newb at packaging Android stuff up. So, if I messed something up, let me know. Both the Source and the LDD file are in this zip.

Things that did have good examples

These are items that I did find help on the web for, but are provided here as a quick jump start.

PreferenceManager

The preferences manager provides an easy way to store data between application start ups. Eventually you probably will provide a dialog to edit that data, but it is a good idea to have in mind what needs to be in it from the start. My app does not have a dialog to edit yet (not sure it will), but it’s mentioned as its something I thought about. It is easy to use

SharedPreferences preferences;
SharedPreferences.Editor preferenceEditor;


in your onCreate override add

preferences = PreferenceManager.getDefaultSharedPreferences(this);
preferenceEditor = preferences.edit();

sensitivityConstant = preferences.getFloat("sensitivityConstant", 4.5f);
throttleMS = preferences.getInt("throttleMS", 100);
ip_to_use = preferences.getString("ip_to_use", "192.168.1.113:8080");

later to change a value use;

preferenceEditor.putString("ip_to_use", ip_to_use);
preferenceEditor.commit();

What the hell is a ‘Toast’? Oh, a messageBox – let’s confuse experienced people and call it something else

A toast is just another name for a message box. There is not a lot more to say about it, other than I looked for messageBox (by that name) for hours and could not find it in Android. Well here it was.

Handling touch on a button (equivalent to onPressed as opposed to onClick)

At one point I needed to move the camera tilt. I initially thought, easy, use onClick, but that really was not appropriate for a button that starts a motion when pressed and stop when not pressed.

The trick is to use touch; Add a button in your layout (in my case with an id of tilt_up) then
after the content is set in your onCreate override;

((Button) findViewById(R.id.tilt_up)).setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View arg0, MotionEvent arg1) {
                int eventType = arg1.getAction();
                if (eventType == MotionEvent.ACTION_DOWN) {
                    if (!actionMotorStarted) {
                        actionMotorStarted = true;
                        sendBTCmessage(BTCommunicator.NO_DELAY, motorAction, 50 * directionAction, 0);
                    }
                    return true;
                } else if (eventType == MotionEvent.ACTION_CANCEL || eventType == MotionEvent.ACTION_UP) {
                    if (actionMotorStarted) {
                        actionMotorStarted = false;
                        sendBTCmessage(BTCommunicator.NO_DELAY, motorAction, 0, 0);
                    }
                    return true;
                }
                return false;
            }
        });

Adding a menu

fairly straightforward, but again, short to the point examples are lacking; add a menu xml (my_menu.xml in my case) file to your project;

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/set_cam_ip" android:title="Camera IP"/>
    <item android:id="@+id/set_nxt_id" android:title="NXT"/>
</menu>

then add these to your main activity class;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.my_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {

            case R.id.set_cam_ip:
                selectIP();
                return true;

            case R.id.set_nxt_id:
                Intent requestNxtConnectIntent = new Intent(this, DeviceListActivity.class);
                startActivityForResult(requestNxtConnectIntent, REQUEST_CONNECT_DEVICE);
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

Things I could not find good examples of, but finally got working, so presented here as examples

 

Custom control – draw a simple circle – I can take it from here.

I fought this one for more than a day. I just want a custom control to paint on and ALL the examples I found were overkill.
Add a class (that extends view);

package com.spiked3.rb;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class JoystickView extends View {

    Paint p = new Paint();
    public float x, y;
    int left, right;
    int myWidth, myHeight;

    final float xNormal = 10f, yNormal = 10f;
    final int A = -10, B = 10;

    public JoystickView(Context context, AttributeSet attrs) {
        super(context, attrs);
        p.setAntiAlias(true);
        p.setStyle(Paint.Style.FILL);
    }

    public void show(float x, float y, int left, int right) {
        this.x = -x;
        this.y = y;
        this.left = left;
        this.right = right;
        invalidate();
    }

    float normalizeFloat(float valueToNormalize, float inLow, float inHigh, float outLow, float outHigh) {
        float scaleRange = outHigh - outLow, valueRange = inHigh - inLow;
        return outLow + (scaleRange * (valueToNormalize - inLow) / valueRange);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // motor power
        p.setColor(Color.GREEN);
        final int barWidth = 20;
        int a = (myWidth / 3);
        int b = a * 2;
        canvas.drawRect(a - (barWidth / 2), myHeight / 2, a + (barWidth / 2), (myHeight / 2) - left, p);
        canvas.drawRect(b - (barWidth / 2), myHeight / 2, b + (barWidth / 2), (myHeight / 2) - right, p);

        // joystick position
        p.setColor(Color.RED);
        int plotX = (int) normalizeFloat(x, -100, 100, 0, myWidth);
        int plotY = (int) normalizeFloat(y, -100, 100, 0, myHeight);
        canvas.drawCircle(plotX, plotY, 10, p);
    }

    @Override
    protected void onSizeChanged(int x1, int y1, int x2, int y2) {
        myWidth = x1;
        myHeight = y1;
    }
}

then add it to your main layout xml;

<com.spiked3.rb.JoystickView
            android:id="@+id/joystickSurfaceView"
            android:background="#FF404040"
            android:layout_marginRight="20dp"
            android:layout_width="352dp" android:layout_height="288dp"/>


Even my example has added ‘stuff’, I hope it doesn’t get in the way.

Webview of a webcam in your application

This one also took me a couple of days to figure out. Adding a webView is simple. The problem was I could not get it to display a motion web page from the web cam. The web cam ‘movie’ displayed properly in all standalone web browsers I tried, but not the web view within my application. Since this was critical to my application, it was a show stopper. Eventually while looking for something else I ran across a line of code that enabled JavaScript. Doh. It is not enabled by default, and there really isn’t any error message I have seen to hint at that. But these 2 lines of code did it;

final WebView webView = (WebView) findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true); // important!

Displaying a dialog for text input

This is another one I spent days on. I found examples, but they didn’t work. Many examples were poorly written. Even posts on StackOverflow offered almost identical solutions, but it turns out they were missing a critical piece. There is a built in function AlertDialog.Builder but the examples (and the function itself) all assume choices, lists, radio buttons. It turns out you CAN add your own layout to it.

create a new layout xml file (ip_address in my case);

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <EditText
            android:inputType="text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/address_edit_text"/>

</LinearLayout>

the use AlertDialog.Builder in your code, after inflating it (on a menu click in my case);

LayoutInflater factory = LayoutInflater.from(this);
        final View textEntryView = factory.inflate(R.layout.ip_address, null);
        final EditText ipAddress = (EditText) textEntryView.findViewById(R.id.address_edit_text);
        ipAddress.setText(ip_to_use, TextView.BufferType.EDITABLE);
        final WebView webView = (WebView) findViewById(R.id.webView1);

        new AlertDialog.Builder(this)
                .setIconAttribute(android.R.attr.alertDialogIcon)
                .setTitle("IP Address for WebCam")
                .setView(textEntryView)
                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        ip_to_use = ipAddress.getText().toString();
                        preferenceEditor.putString("ip_to_use", ip_to_use);
                        preferenceEditor.commit();
                        // java script full screen page from ipWebcam app
                        webView.getSettings().setJavaScriptEnabled(true);   // important!
                        webView.loadUrl(String.format("http://%s/jsfs.html", ip_to_use));
                    }
                })
                .create().show();

The part that was missing in examples I found was the critical need to use the inflated view in the call to findById. I thought I had tried that once before and it did not work, but I probably had something else messed up. I also learned that some cases Android expects all lower case letters in an ID name, but doesn’t really tell you when. I can’t tell you when, but if something looks right to me and doesn’t work, I’ll change the name to all lower case and most of the time it fixes the problem. Nice huh?

Robotic/Generic

Joystick to differential drive algorithm; DiamondToolbox

As an added bonus in my code you will find some support classes for Doug Taylor’s DiamondPoint differential drive equation. If you are doing anything in robotics that requires a joystick to control a differential drive, this is it. It outperforms all other algorithms I have seen. The others I tried could do forward and reverse OK, but came up short for turning. Doug’s algorithm will do true full power available turns. I tried 3 different algorithms out (they are all still in my code if you want to look) and I could see the results on the joystick custom control I wrote. You can see how the power is more ‘proper’ with the DiamondPoint Algorithm. Doug has graciously permitted me to redistribute my conversion to Java of his algorithm. The original discussion is here;
http://social.msdn.microsoft.com/Forums/en-US/roboticscommunity/thread/1fbec2bf-680b-4d4e-8b84-8f6502132727

a generic normalize function

It showed up in code a little earlier, but I needed a generic use all the time function to normalize values. I found some ‘psuedo’ code on the web for such, and many real code examples to normalize all values in a collection, but not something single value oriented. So I include it here, just as another time saving ‘just copy his’ function (see normalizeFloat in the JoystickView class above).

Posted in Lego, Robotics | Tagged , , , , , | Leave a comment

Roborealm AVM Navigator SPAM

Roborealm AVM Navigator (multilevel decomposition of recognition matrices) : WTF dudes? leaving inappropriate SPAM here is not the way to promote your commercial product. But since you did, where do I send the advertising bill? Losers.

Update: Look losers, there is a post on robotC where someone was looking to do SLAM;
“I am using a LEGO MINDSTORMS NXT. I have an ultrasonic sensor”
I asked him after 4 months if he ever got anywhere, as I was doing a similar thing http://www.spiked3.com/?p=162. You first replied on RobotC’s web site, that we should use your product, then also commented the same on MY blog. Even though your commercial product has nothing to do with RobotC or LEGO Nxt and uses a video camera (webcam). I explicitly said I did not want to use someone else’s code. Then you cried when I called you out on it, for posting links for the sole purpose of upping your Google link counts. Your replies even had 1 or 2 unnecessary links to your product and your intentions are quite clear. Your product has nothing to do with what either of us were talking about, AND you do not educate us as to your wonderful algorithm, instead its buried in a compiled DLL file, that costs more than RobotC to obtain. If that is not SPAM, what is? It exactly matches the definition of all the other posts that Akismet deletes as SPAM, so why is yours different? Some people understand how SPAM works, some do not. In this case, Roborealm AVM Navigator SPAMMED someone who does. So unless you can show me the algorithm of Roborealm AVM Navigator, that works on a LEGO Nxt with a Range finder, shut the F up.

Posted in Robotics | Tagged , , , , , , , | Leave a comment

IntelliJ

I complain enough about buggy Eclipse, I thought it would be appropriate to give a thanks to IntelliJ for a good product. I recently wrapped a new tele-operation rover with the NXT and an Android phone on it running IpWebCam and an Android tablet running custom software written using IntelliJ.

This is a newer version of something I did a few years ago. The intent was to have something kids could ‘play’ with at the upcoming Robothon. You can drive the NXT around using tilt, and seeing what the NXT sees. I did not add sensor information as before since at this time the intent is more just ‘fun’.

The code took a while to get working. Android development has changed quite a bit and I was not that advanced in it to begin with it. I guess it will change even more if today’s jury decision sticks; Java is not open, and anyone who implements it (IBM you are next) has to pay Oracle a lot of money. This may be the end of Java, and I bet a huge change in Android is shortcoming. The C# port is almost completed and protected by Microsoft commitment to NOT challenge any one who implements C#. Google had considered C# early. I bet they wish they had made the other decision now.  Anyhow, I plan on cleaning up my code as it uses quite a bit of GPL 3 stuff, and then releasing it, along with a LEGO LDD file, with a Android shortcut tutorial (it uses LCP so no Nxt programming is needed). I found so many irrelevant and plain wrong examples on the web. A guide of ‘just give me what I need to know’ with out added bullcrap is needed. There are some pitiful code examples out there.

Posted in Lego, Robotics | Leave a comment

Unimog in progress

Wow. The design that goes into these things blows me away. I think the 8043 excavator was a bit more technical gear wise, but this is more technical car suspension wise. But while I’m bragging about the design, there are also a few areas, where to me they did something the stupid way. Does anyone have any insight into the design process? It’s obvious they don’t use just LEGO digital designer (although I feel it would be a solid foundation for a more advanced app).

And I will say I’m pretty happy with the cheapo little light tent. Nothing great, but it gets the job done. When I got it, it was $29. I’m not sure it is worth more than that. This looks the same.

Posted in Lego | Leave a comment

Robotic revolution – real progress

There has been one significant event in robotics/AI in my lifetime; IBM Watson.

I just started reading a book on what I believe is one of the few significant events in robotics/AI in the last 30 years;

http://www.amazon.com/Final-Jeopardy-Machine-Quest-Everything/dp/0547483163/ref=sr_1_1?ie=UTF8&qid=1334689197&sr=8-1

It does not get enough press, considering the ramifications. Sure machines got physically stronger than man, but that happened in the 17th century (or even earlier). Sure machines beat man at chess, but that was just pre-evaluating mathematically constrained limited choices. But when Watson beat champions at a knowledge game, in natural and twisted English, it was indeed, new and significant / unexpected.

I am surprised to learn that the team admits though, it is ‘cheating’. It is throwing horsepower at mathematically arriving at probable best answers. Watson does not think. Thinking intelligence consists of sensors (eyes, ears, touch etc), symbols and ideas. Watson is able to manage 2 of these, sensors and symbols. But ask the current jeopardy champion what man should research next in his quest to improve the human race, and you get an empty blue screen.

To answer a forum question I recently saw posted, “Will computers wirte (sic) their own programs in future ?” The answer is maybe, but probably not for a very very long time.

Update; I finished the book, and I am both happy and sad. It was a decently written book, and I have had a hard time making it though books lately, but it was well enough written I stuck to it. I am happy as I see beating humans as an accomplishment. I am unhappy because it beat them with what is the mechanical equivalent of gearing. Rather than being smart, it instead was dumb and fast with a lot of information. The two appear similar, and maybe that is ok for now. I guess I’m just a little disappointed with science zeroing in on the big bang and entanglement, maybe even the dark matter question, we still have no idea how we think. Part of me has a gut feeling those areas of science (entanglement and thinking) might be closer related than is generally discussed.

Posted in Robotics | Leave a comment

More on the Robotics Revolution

I know, it is goofy but this is something I sometimes lose sleep over. People are unhappy when I explain that there is no robotics revolution. I mean they really get unhappy, sometimes even angry. So, why is it I disagree with what seems like everyone? Perhaps the explanations is that the ‘Robotics revolution’ is not so much an revolution in robotics, but a growth in what we call a robot.

For example, the Davinci Surgical Robot was featured in the current Servo Magazine, a magazine for the robotics hobby. But the manufacturers themselves are more on my side. They point out it is not, nor will it ever be a robot. It is a precise remote control device, with some assists from sensors. I just finished looking at the JPL website, they are very careful not to call their devices robots, but instead ‘robotic rovers’, but everyone else seems to be perfectly comfortable describing them as just robots.

There is an entire division within robotics called Tele-Operation. This describes devices that are used to allow an operator to interact with the environment in a different geographic location. They are often referred to as robots, but they are simply remote controlled vehicles, with a camera mounted on them. They may have some sensors to avoid running into things, but they are far from what I consider a robot.

And how about those who describe the DARPA vehicle challenge contestants as robots? I car that can follow a line, no matter how big or small, is not to me a robot. Nor is a self parking car.

I guess to me, the word robot conjures up a expectation of AI. The robots from lost in space, forbidden plantet think like humans. One person (who claimed to be an educator in robotics) told me that because those robots were mechanically inefficient, they would be terrible robots :| I guess him and I will always disagree on what a robot is.

BTW, from here on I will refer to my RC truck as a robot, just to make my point. That way when someone says “no it’s not”, I can agree with them :)

My Semi autonomous, flight capable 4 wheeled robot

Posted in Robotics | 2 Comments

Uh oh, No NXT Apps for Windows 8 Tablets?

I have not found a way – apparently I am not alone;

http://stackoverflow.com/q/10089064/825162

So much for a Windows 8 Tablet TeleOp app. Guess it’s back to Android, doh.

update: A couple of hours into it. I have new respect for those who do Java/Eclipse for a living. Not because they’re greater, but because they are able to be productive in that environment. I know you hate MS, but you should try it for a while, if only just to go back and demand more from your side.

Its worse than I thought. Current eclipse with current java is unusable on windows. The editor can not even display your file correctly and you end up typing and deleting stuff on lines that aren’t even displayed. Some people I asked said they no longer will use eclipse :( Any alternatives for Android development?

IntelliJ So far 1000 times better than Eclipse. Its fast and supports Android with only a few quirks, nothing worse than Eclipse. Why do they give it away? I would gladly pay a little for it, and it is NOT open source (which is probably why it is 1000 times better). Not quite worth the $200 they want for the ultimate version that adds no features I want, but certainly worth more than free.

Posted in Lego, Robotics | Leave a comment

LEGO Unimog

Lego 8110 Mercedes Unimog :) I’m busy for next week or so.

Posted in Lego | Leave a comment

Parallax Scribbler

If you are in the Seattle area and want an as new Scribbler 2, let me know. It has the IPRE Fluke with it.  It has never really been used as the provided software managed to wipe out my computer, and I never bothered trying again after reformatting.

Purchased in November for about $250 total, $100  $50 cup of coffee will take it.

Update: Gone. It has a new home now.

Posted in Robotics | Leave a comment