EV3 Sumo Robot

lifting a box

After a long period of silence, I finally made some things with my EV3. Last time the tools where not really ready, but now everything works great.

I used ev3dev and python-ev3 to build this bulldozer. Watching sumo matches at LEGO World, I saw a few things that do and don’t work.

A lot of people seem to go for blades and hammers, but unless you actually want to destroy the robot, they are useless. Treads sound like a good idea, but wheels have more grip in practice. Make sure the wheels don’t fall off. Encased wheels are the best.

The goal is to push the other robot off the table, so the more powered rubber the better. Four wheel drive is better than rear wheel drive, but rear wheel drive is still much better than front wheel drive.

It’s all about pushing. The only useful thing besides pushing forward is pushing up or sideways. Pushing up is the easiest, because you have the floor to back you up. It also pushes the opponent’s wheels off the ground. This lead me to the following design.

I used two pairs of driven rear wheels on a pivot, so even if I’m lifted, all four remain in contact with the ground. They are geared down, which means I’m slow, but powerful. All the weight of the motors and EV3 is directly above the wheel, for maximum grip.

On the front there is a lift arm, using a worm wheel and a very solid construction. I went through several iterations, improving the strength each time. On the first iteration, it was to weak, but its wedge shape still lifted my opponent a little.

The code is quite simple. Push forward. When you reach the edge, turn around. When something hits the bumper, raise the arm.

from ev3 import lego
import time
import select
import os

# Utility for waiting on the motor.
p = select.poll()
callbacks = {}

def poll():
    for fd, mask in p.poll(0):
        os.lseek(fd, 0, os.SEEK_SET)
        state = os.read(fd, 16)
        if state == "idle\n":
            p.unregister(fd)
            os.close(fd)
            callbacks.pop(fd)()

def on_completion(motor, callback):
    fd = os.open(motor.sys_path + '/state', os.O_RDONLY)
    callbacks[fd] = callback
    os.read(fd, 16)
    p.register(fd, select.POLLPRI)

# Initiate all sensors and motors
l = lego.LargeMotor("A")
r = lego.LargeMotor("D")
lift = lego.MediumMotor()

dist = lego.InfraredSensor()
line = lego.ColorSensor()
touch = lego.TouchSensor()

# reset the motors
l.reset()
r.reset()
lift.reset()

try:
    # run forwards
    l.run_forever(100, regulation_mode=False)
    r.run_forever(100, regulation_mode=False)
    # main loop
    while True:
        poll()
        if touch.is_pushed and lift.state == "idle":
            # we hit something, raise the arm!
            lift.run_position_limited(-3000, 1000)
            on_completion(lift, lambda: lift.run_position_limited(0, 1000))
        elif line.reflect < 20 and l.duty_cycle > 0 and r.duty_cycle > 0:
            # we reached the edge, back up and scan for opponent
            l.run_time_limited(1000, -100)
            on_completion(l, lambda: l.run_forever(100))
            r.run_forever(-100)
        elif dist.prox < 50:
            # found opponent, charge!!!
            r.run_forever(100)
            l.run_forever(100)
finally:
    # stop motors and lower arm
    l.stop()
    r.stop()
    lift.run_position_limited(0, 1000)
Posted in Code, Robots | Leave a comment

Final Excavator

I found a nice place to put the RCX and NXT and got together some remotes to play with it.

The video and slideshow might not work on the RSS feed or mailing list. Check the website.

Posted in Uncategorized | Leave a comment

Excavator wheel base

Today I took out the RCX and made a wheelbase for the NXT excavator arm I made earlier.

I am satisfied with the look and maneuverability, the only problem remains where to put the RCX. Maybe I can put both the NXT and the RCX on the arm, or make some room in the wheelbase.

It will also be interesting to control the whole maschine. The NXT and RCX can’t really talk to each other, but both can talk to the computer over Bluetooth and Infrared respectivly. So maybe I wil make a command centre on the computer to control both devices.

Posted in Robots | Leave a comment

Excavator

IMG_0018

Today I spent some time building an excavator. I had to choose between controlling all parts of the arm and letting some parts move together mechanically.

I chose to do the former, which means I don’t have any motors left for the chassis, but can freely move all parts of the arm.

Maybe another NXT or RCX kit could serve as the base, which also needs 3 motors: 2 to drive and 1 for the rotating platform.

Posted in Uncategorized | Leave a comment

All NXT building instructions now free

I thought long and hard about this, as a lot of effort went into making these building instructions, but I concluded that I feel better about sharing them with as many people as possible than sharing them with a handful and making a few bucks.

So I’m happy to announce that all the instructions I made so far will be available for free. Go check them out.

I haven’t been writing a whole lot in the past months, but I feel some things breeding and I’m also super excited about the new EV3 coming out this year.

Posted in Uncategorized | Leave a comment

RCX Plotter with Glidewheel

I modified the UBS plotter model to work with the NXT using 2 glidewheels and a normal converter between NXT and classic LEGO connectors.

The original model has two spoke wheels with touch sensors on them, to count the rotations. I replaced these with glidewheels.

Since the UBS is modular, it should be fairly simple to power other models with the same glidewheel-enhanced modules.

I also slightly modified the compressor gear train and paper feed to be more reliable with my old LEGO. Other than that, the model is completely original.

For a nice introduction to the original model, I refer you to Henrik Bækdahl.

Posted in Robots | Leave a comment

Mindsensors Glidewheel

IMG_0110

I just got two Glidewheels from Mindsensors for testing. The Glidewheel allows you to integrate other motors into your NXT models, providing precise control over even the oldest 9V motors.

The Glidewheel is designed for Power Functions motors, but works just as well for my RCX motors.

The hard part of using them with RCX LEGO is that they don’t fit directly or close to the RCX motors. You’ll have to mount them elsewhere and stick an axle through them. This is further complicated by the stud-based RCX LEGO.

The first thing I made with them is this small car that uses a drive and steer motor. Even with the rotation sensor that you could buy for the RCX, it was incredibly hard to steer a robot like this.

With the Glidewheel it is incredibly easy. Well, almost. My first attempt looked much like my past attempts with the RCX.

The RCX motors are a lot faster than the NXT motors, so what happens is that the PID controller in the NXT starts overreacting.

To stop this, I used an algorithm called gradual descent(or twiddle, as prof Thrun calls it), which basically modifies P, I or D a little, and sees if it gets better or worse.

float pid[];
float delta[];
int err;
int newerr;
mutex running;

task record() {
	newerr = 0;
	int tacho;
	Acquire(running);
	for(int i=0; i<200; i++) {
		tacho = MotorRotationCount(OUT_A);
		newerr += abs(tacho - 365);
		Wait(10);
	}
	Release(running);
}

inline void run() {
	ResetRotationCount(OUT_A);
	start record;
	RotateMotorPID(OUT_A, 100, 365, pid[0], pid[1], pid[2]);
	Acquire(running);
	printf("%d", newerr)
	Release(running);
}


task main() {
	ArrayInit(pid, 32, 3);
	ArrayInit(delta, 5, 3);
	err = INT_MAX;
	run();
	while(ArraySum(delta, NA, NA) > 0.1) {
		NumOut(0, LCD_LINE2, pid[0]);
		NumOut(0, LCD_LINE3, pid[1]);
		NumOut(0, LCD_LINE4, pid[2]);
		for(int i=0; i<3; i++) {
			pid[i] += delta[i];
			run();
			if(newerr < err) {
				err = newerr;
				delta[i] *= 1.1;
			} else {
				pid[i] -= 2*delta[i];
				run();
				if(newerr < err) {
					err = newerr;
					delta[i] *= 1.1;
				} else {
					pid[i] += delta[i];
					delta *= 0.9;
				}
			}
		}
	}
	PlayTone(432,1000);
	Wait(10000);
}

The result of this code for my little car was

P I D
Default 96 32 32
Free 40 40 32
Load 40 32 40

Inserting these values in my code, I get this smooth motion.

Code:

mutex inControl;

task avoid() {
	while(true) {
		while(SensorUS(IN_4)>30);
		Acquire(inControl);
		PosRegSetAngle(OUT_C, 90);
		OnRevRegPID(OUT_A, 50, OUT_REGMODE_SPEED, 40, 32, 40);
		Wait(2000);
		OnFwdRegPID(OUT_A, 50, OUT_REGMODE_SPEED, 40, 32, 40);
		Release(inControl);
	}
}

task turn() {
        while(true) {
                Wait(1000);
		Acquire(inControl);
                PosRegSetAngle(OUT_C, 90);
		Release(inControl);
                Wait(1000);
		Acquire(inControl);
                PosRegSetAngle(OUT_C, -90);
		Release(inControl);
                Wait(1000);
		Acquire(inControl);
                PosRegSetAngle(OUT_C, 0);
		Release(inControl);
        }       

}

task main() {
	SetSensorLowspeed(IN_4);
        OnFwdRegPID(OUT_A, 50, OUT_REGMODE_SPEED, 40, 32, 40);
        PosRegEnable(OUT_C, 40, 40, 32);
	Precedes(turn, avoid);
}

Posted in Uncategorized | Leave a comment

Face Tracking Laptop Crawler

photo

First post from the US!

I can’t really do nice photography, video and building instructions here, but I did make a robot.

This thing sits under your laptop, and can drive it around and tilt the screen. The idea is that it will always face you, and keep a fixed distance too.

It uses the webcam of my laptop to track my face using OpenCV from Python.

It could also keep a fixed distance using the ultrasonic sensor, but this is not implemented.

Posted in Uncategorized | Leave a comment

NXT in-line skater

skater

I found a video that features a skating robot, it moves, but skating? I did a lot of skating myself, so I started to think about a better skating movement.

It occurred to me that while skating around pylons, you don’t need to take your skates of the ground. What you do instead is hard to explain.

I tried to explain my idea to anyone who’d listen in #mindboards, but to no avail. You just have to see it with your own eyes.

It is a really fun thing to build and play around with. I suspect you can find more efficient and inexplicable ways to move and turn.

Get the building instructions for this model

This is the Mirah code I used in the video:

import lejos.nxt.Motor
import lejos.nxt.Button

def align()
	Motor.A.rotate(360 - (Motor.A.getTachoCount() % 360))
	Motor.C.rotate(360 - (Motor.C.getTachoCount() % 360))
end

speed = 150
Motor.A.setSpeed(speed)
Motor.C.setSpeed(speed)

Motor.A.forward()
Motor.C.forward()

Thread.sleep(20000)

Motor.A.stop()
Motor.C.stop()

align()

Motor.A.backward()
Motor.C.forward()

Thread.sleep(20000)

align()

Motor.A.forward()
Motor.C.forward()

Button.waitForAnyPress()
Posted in Building Instructions, Robots | Leave a comment

Coming to America

I am going to attend Hacker School this summer. While I will fill half of my suitcase with LEGO, I won’t be posting regularly.

With that said, I hope there will be some exciting projects I can share with you. Have a great summer… or winter!

Posted in Uncategorized | Leave a comment
  • Get new ideas and models per email

    * = required field
  • Categories