I know this is a rather silly robot. It does nothing at all, and it’s not very beautiful either. I guess I just want to remind you that it’s important to just play without expectations or goals.
According to John Cleese, it is very useful to attempt something impossible sometimes. This often puts your mind in a new perspective, leading to new ideas.
Reading a CD with a light sensor is obviously not going to work, but maybe there are other ways to read data with the EV3?
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.
[gallery columns=”2” ids=”534,532,533,535”]
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.
fromev3importlegoimporttimeimportselectimportos# Utility for waiting on the motor.
p=select.poll()callbacks={}defpoll():forfd,maskinp.poll(0):os.lseek(fd,0,os.SEEK_SET)state=os.read(fd,16)ifstate=="idle\n":p.unregister(fd)os.close(fd)callbacks.pop(fd)()defon_completion(motor,callback):fd=os.open(motor.sys_path+'/state',os.O_RDONLY)callbacks[fd]=callbackos.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
whileTrue:poll()iftouch.is_pushedandlift.state=="idle":# we hit something, raise the arm!
lift.run_position_limited(-3000,1000)on_completion(lift,lambda:lift.run_position_limited(0,1000))elifline.reflect<20andl.duty_cycle>0andr.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)elifdist.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)
I was reflecting on all the fun I’m having with my Arduino GPS system,
and found something interesting.
I could have used a Raspi, and have some actual RAM, storage and screen.
But by constraining myself to the bare minimum,
I created all sorts of wonderful algorithms and hacks.
This is maybe a known thing, but it bears repeating: constraints foster creativity.
Writing “a story” is much harder than wiritng “a story about the first brick of the city hall of Amsterdam”.
By narrowing down the search space, your brain can do a much more exhaustive search.
An example that comes to mind is LuaJIT.
Lua is found in all sorts of places, so a small binary size is a virtue.
Someone told me it fits on a floppy, which I found is true.
Consequently, it contains wonderful things like this.
[A recursive backpropagation algorithm with backtracking, employing
skip-list lookup and round-robin caching, emitting stack operations
on-the-fly for a stack-based interpreter – and all of that in a meager
kilobyte? Yep, compilers are a great treasure chest. Throw away your
textbooks and read the codebase of a compiler today!]
Once upon a time, Guy Steele set a high tax on special forms (syn-tax, ha, ha…),
and consequently invented Scheme.
Later, John Shutt thought that wasn’t enough, and invented Kernel.
Clojure on the onther hand, is only constrained to be practical.
What is your favourite piece of constrained software?
How do you set constraints for yourself?