Arc Reactors And Animatronics

Status
Not open for further replies.
Honus: I presume your using a arduino as your controller, as you are using one in your desktop cnc build. Anyways, a quick and imo more reliable way to do motion tracking like that is simply to place the 3 axis gryo in the head, preferably the center of the brow. Then read the inputs nearly every 10ms (which i believe is the arduino's read threshold). by constantly reading and comparing it, and every time it changes moving the gun TO that direction. Best choice is to first figure out the entire range of the gun to have, that will give you the movement range of your head that will dictate tracking. Then just write a if around the tracking movement structure to ensure that the head is looking within that movement cone. you just have to remember to zero it out first, ie look stright ahead when you boot the board up to get your baseline.



yeah alas the Speed of tracking won't ever match smoothly when moving at a normal pace, only when moving slowly, then again the original pred gun was actually controlled by guys outside the suit, so it never did track perfectly, just slowly tracked and then stopped where the character stopped looking (aka at his target).



Your switch scheme is pretty decent, if a bit redundant. Did you consider just using a toggle? ie 1 press to turn on, 2 presses to return to zero and off?
 
Fox w said:
Honus: I presume your using a arduino as your controller, as you are using one in your desktop cnc build. Anyways, a quick and imo more reliable way to do motion tracking like that is simply to place the 3 axis gryo in the head, preferably the center of the brow. Then read the inputs nearly every 10ms (which i believe is the arduino's read threshold). by constantly reading and comparing it, and every time it changes moving the gun TO that direction. Best choice is to first figure out the entire range of the gun to have, that will give you the movement range of your head that will dictate tracking. Then just write a if around the tracking movement structure to ensure that the head is looking within that movement cone. you just have to remember to zero it out first, ie look stright ahead when you boot the board up to get your baseline.



yeah alas the Speed of tracking won't ever match smoothly when moving at a normal pace, only when moving slowly, then again the original pred gun was actually controlled by guys outside the suit, so it never did track perfectly, just slowly tracked and then stopped where the character stopped looking (aka at his target).



Your switch scheme is pretty decent, if a bit redundant. Did you consider just using a toggle? ie 1 press to turn on, 2 presses to return to zero and off?



Yep it's Arduino- main reason being cost and accessibility. I've used the MAKE controller as well and it's a lot more powerful but it's kind of overkill. I'm well aware of how all the original Pred stuff was done using R/C- pretty standard stuff.



A toggle didn't work for the Pred cannon because the way I wrote the code you need one button to raise the cannon into position and hold it there in standby mode and then another button push activates firing.



The problem with gyros is that you need two of them, preferably with an accelerometer to account for drift as well as front/rear tilt (pitch). One gyro really won't work well because it will respond to whole body rotation as well as just head rotation, so you would need one IMU at the head and another at the cannon base and then you have to write some code to differentiate between the two. Gyros really only sense change in angular velocity so its output only changes with respect to movement and it will reset itself once you stop rotating your body- the cannon will quickly become out of sync with your movements. That's why to really do it right you need a multiple DOF IMU and you need two of them for true head tracking. Most of the systems I've seen that people post online as a head tracking system for R/C or video control have very poor yaw control and this is why. And they don't even have to deal with the body rotation issue as they can sit in a chair- not an option for costuming.



There are IMUs available now that have on board processing and are programmed to account for drift so some of the hard work is done for you but you would still have to factor in the difference output of two of them and then generate your necessary servo movement values from that. It can be done but it's pretty darn expensive.



What I did was to basically fake it by strictly using the accelerometer inputs- when looking sideways you just need to tilt your head to the side like a bird for yaw (rotation) control. The accelerometer reads the tilt and moves everything accordingly- the pitch function is normal. It's relatively simple and it's cheap- you could build a War Machine setup using a $20 Wii Nunchuck controller and a $20 Arduino board with two strong servos, some LEDs, a motor to spin the barrels and batteries and you're good to go. If you want to add sound effects then figure in another $60 or so, depending on how loud you want it. The Predator setup is a fair bit more complex as the cannon has to unfold and raise up into the standby firing position, so there is an additional servo and controller involved.



For costuming all you need to do is provide the illusion. When I started the project with a friend three years ago we wanted something that anyone could build from readily available building blocks to add some cool animatronics to their Predator costume without spending a ton of cash.



Maybe I'll throw up the source code and a diagram for a War Machine cannon later...



Here's a pic of the early Pred cannon mechanism- it's very different now and is gear driven.

gallery_22290_2346_740691.jpg
 
Last edited by a moderator:
Honus,

Great work on your creations!

A friend of mine sent me a link to your indestructibles page a while back.

I am diggin' on the "New style" Arc Reactor hard core. So since we have had some free time at work, I decided to give it a try.

One of these will be used in the War Machine suit I have started pepping. Thanks for all of the pointers and pictures you have posted.



Again, Awesome stuff!









I hope you like them so far.
 
VersionUp said:
the Proton pack and the trap are B.A.!



Thanks! They could have been much better but I figured it wasn't too bad considering I built two complete costumes in two weeks for myself and a friend. That was a fun Halloween...
 
Last edited by a moderator:
Sweet! Honus, I grabbed your Arc Reactor instructions off of Instructables a month or so ago. Trying to decide the best way to make one myself, given my limited fabrication ability (I have no machining devices, although I'm a fair hand with hand tools and a Dremel), but your instructions will go a long way to making that easier. My stepdaughter wants me to build her one, too. She also wants the armor, of course, but I've told her we'd start with the Arc Reactor and see about the armor later.
 
Glad to help! I have three boys and I'm sure as they get older they'll want all kinds of cool costumes. :)



I'm in the process of making a new reactor now that will be much easier to make- I think I've found a way to greatly simplify the circuit board and spider construction as that seems to be where the greatest difficulty is for most people.
 
ChaoBreeder said:
Man, I knew the name Honus rang a bell, welcome to the 405th! If you don't mind me asking, since you are the animatronics expert, can I rig a RC car to the inside of the saw doll's (in my avatar) mouth to make it move?



Like this:

http://i240.photobucket.com/albums/ff32/evildrew81/people%20and%20stuff/saw_doll_tv.gif



You can make the mouth move by using a single servo and receiver from your R/C car. Just make the jaw hinge and have the servo move the jaw using a bellcrank. It's very simple.
 
Last edited by a moderator:
Thank you for your help. I had servos mixed up with something else...But I have have another question, what is a bellcrank? And how can you make one? Sorry for the trouble.
 
ChaoBreeder said:
Thank you for your help. I had servos mixed up with something else...But I have have another question, what is a bellcrank? And how can you make one? Sorry for the trouble.



A bellcrank is basically an "L" shaped bracket with a hole in it for a pivot. Take a look here at some pics of a simple animatronic head and look specifically at how they make the jaw move.



http://www.medonis.com/max_assby.html
 
Last edited by a moderator:
Honus said:
Glad to help! I have three boys and I'm sure as they get older they'll want all kinds of cool costumes. :)



I'm in the process of making a new reactor now that will be much easier to make- I think I've found a way to greatly simplify the circuit board and spider construction as that seems to be where the greatest difficulty is for most people.



Excellent! The board I figured I could handle, but I was wondering how I was going to do the spider. Looking forward to your revised instructions.
 
Last edited by a moderator:
So here's what the new reactor will look like- it's based on the MkII version. It should be shallow enough to fit in most armor.
ArcReactorMkIISketch.jpg
 
Here's a schematic for setting up an animatronic War Machine cannon with sound effects.
ArduinoConnections2.png


This uses the Arduino micrcontroller, which is very low cost and easy to use

There's more info about Arduino here- http://arduino.cc
Lots of different companies build Arduino boards and I buy mine from Sparkfun- http://www.sparkfun.com/commerce/categories.php?c=103
The easiest board for first timers to use is probably this one- http://arduino.cc/en/Main/ArduinoBoardDuemilanove

The nice thing about the Duemilanove board is that it has built in USB, shield compatibility and 3.3v output for powering sensors so it's very easy to use. A shield is simply a board that plugs on top of the Arduino board and allows you to connect stuff like sensors and additional electronics.

There are all kinds of shields but for this what you want is a prototyping shield like this one- http://www.sparkfun.com/commerce/produc ... ts_id=7914
Adafruit sells a nice one as well- http://www.adafruit.com/index.php?main_ ... ucts_id=51

Once you get an Arduino you need to upload some code- you simply cut and paste it into the Arduino window, hit verify and then upload and you're good to go.

For getting started with Arduino there are some great tutorials here: http://www.ladyada.net/learn/arduino/index.html

So this diagram shows how you would connect a Wii Nunchuck and the other necessary electronics to an Arduino. The Wii Nunchuck has four wires- red, white, green and yellow. The red and white wires are for power and ground so they are connected to 3.3v and ground pins. The green and yellow wires are for data and clock and are connected to analog input pins 4 and 5. Simple.

On the opposite side are the output pins. Pins 4,5,6 and 7 are for connecting servos. Servos have 3 wires- signal, power and ground. The signal wire is the yellow wire and power is red and ground is black. Sometimes the signal wire is white depending on servo brand. The signal wire is connected to the Arduino output pin. A note about servos and microcontrollers- servos generate a fair bit of electrical noise so it's best to provide them with their own power supply.

Pin 10 is an output for connecting a sound board- I use the Adafruit Wave shield- http://www.adafruit.com/index.php?main_ ... ucts_id=94

Pin 11 is for controlling a LED. Arduinos have a maximum output of 40mA for each pin so if you want to use something like a Luxeon LED you will need to use a transistor (basically an electronic switch) in order to provide more power. A TIP120 transistor is only a couple of bucks and can provide a fair bit of power. When Pin 11 goes HIGH the LED turns on.

Pin 12 is for connecting a motor (this motor would be something like a cordless drill motor to spin the cannon barrels.) Since this would be a continuous speed motor all you would need is another transistor. When Pin 12 goes HIGH the motor turns on.

The 1K resistors are there to protect the Arduino output pins. The blocking diode on the motor transistor is there to protect the transistor from back voltage from the motor.

I wrote this particular code in 2007 to interface a Nintendo Wii Nunchuck controller to an Arduino. The Nunchuck controller has a 3 axis accelerometer, joystick and two buttons. I never used the Z axis of the accelerometer so I left that out. So the way this works is you connect the Nunchuck to your Arduino and it reads the inputs and translates them into servo movements to move your cannon. So by using this code you can move the joystick and the cannon will move up/down and rotate right/left and pressing the buttons will make the cannon rotate ans well as light up LEDs in the barrels and even allow the firing sound (more on that later.) If you want you can use the accelerometer functions to move the cannon instead.

I took apart the Nunchuck and removed the joystick from the board. I detached the finger buttons from the board and made an extension cable. The board is then mounted inside the helmet. So with this setup you can mount the Wii Nunchuck board in the top of your helmet (try to get it as level as possible) and you'll have a head tracking cannon system. Push one button and the barrels will spin and pushing the second button will make the LED (you could put one in each barrel) light up and trigger the firing sound.

WiiBoardTop.jpg

WiiBoardBottom.jpg

WiiFingerButtons.jpg
 
So here's the code you need for the main controller- this will give you access to all the Wii Nunchuck functions (except the Z axis, since I never really used it- but it's easy to add back in.)

Here's the first half of the code-

#include <Wire.h>

int controlPin1 = 11; // Control pin for motor using c button
int transistorPin1 = 12; // Control pin for LED using z button
int transistorPin2 = 10; // Control pin for cannon sound using z button
int servoPin1 = 7; // Control pin for servo motor 1 using accelerometer x axis
int servoPin2 = 6; // Control pin for servo motor 2 using accelerometer y axis
int servoPin3 = 5; // Control pin for servo motor 3 using joystick x axis
int servoPin4 = 4; // Control pin for servo motor 4 using joystick y axis

int pulseWidth1 = 0; // Amount to pulse the servo 1
int pulseWidth2 = 0; // Amount to pulse the servo 2
int pulseWidth3 = 0; // Amount to pulse the servo 3
int pulseWidth4 = 0; // Amount to pulse the servo 4

int refreshTime = 40; // the time in millisecs needed in between pulses
long lastPulse1;
long lastPulse2;
long lastPulse3;
long lastPulse4;
int minPulse = 700; // minimum pulse width
int loop_cnt=0;

void setup()
{
Serial.begin(19200);
pinMode(controlPin1, OUTPUT); // Set control pin 1 as output
pinMode(transistorPin1, OUTPUT); // Set transistor pin 1 as output
pinMode(transistorPin2, OUTPUT); // Set transistor pin 2 as output
pinMode(servoPin1, OUTPUT); // Set servo pin 1 as an output pin
pinMode(servoPin2, OUTPUT); // Set servo pin 2 as an output pin
pinMode(servoPin3, OUTPUT); // Set servo pin 3 as an output pin
pinMode(servoPin4, OUTPUT); // Set servo pin 4 as an output pin
pulseWidth1 = minPulse; // Set the motor position to the minimum
pulseWidth2 = minPulse; // Set the motor position to the minimum
pulseWidth3 = minPulse; // Set the motor position to the minimum
pulseWidth4 = minPulse; // Set the motor position to the minimum

nunchuck_init(); // send the initilization handshake
Serial.print("NunchuckServo ready\n");
}

void loop()
{
checkNunchuck1();
updateServo1(); // update servo 1 position
checkNunchuck2();
updateServo2(); // update servo 2 position
checkNunchuck3();
updateServo3(); // update servo 3 position
checkNunchuck4();
updateServo4(); // update servo 4 position



if( nunchuck_cbutton() ) // turn on control pin 1 if c button is pressed
digitalWrite(controlPin1, HIGH);
else
digitalWrite(controlPin1, LOW);

if( nunchuck_zbutton() ) // turn on transistor pin 2 if z button is pressed
digitalWrite(transistorPin2, HIGH);
else
digitalWrite(transistorPin2, LOW);

if( nunchuck_zbutton() ) // turn on transistor pin 1 if z button is pressed
digitalWrite(transistorPin1, HIGH);
else
digitalWrite(transistorPin1, LOW);







delay(1); // this is here to give a known time per loop
}


void checkNunchuck1()
{
if( loop_cnt > 100 ) { // loop()s is every 1msec, this is every 100msec

nunchuck_get_data();
nunchuck_print_data();

float tilt = nunchuck_accelx(); // x-axis, in this case ranges from ~70 - ~185
tilt = (tilt - 70) * 1.5; // convert to angle in degrees, roughly
pulseWidth1 = (tilt * 9) + minPulse; // convert angle to microseconds

loop_cnt = 0; // reset for
}
loop_cnt++;

}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo1()
{
// pulse the servo again if rhe refresh time (20 ms) have passed:
if (millis() - lastPulse1 >= refreshTime) {
digitalWrite(servoPin1, HIGH); // Turn the motor on
delayMicroseconds(pulseWidth1); // Length of the pulse sets the motor position
digitalWrite(servoPin1, LOW); // Turn the motor off
lastPulse1 = millis(); // save the time of the last pulse
}
}

void checkNunchuck2()
{
if( loop_cnt > 100 ) { // loop()s is every 1msec, this is every 100msec

nunchuck_get_data();
nunchuck_print_data();

float tilt = nunchuck_accely(); // y-axis, in this case ranges from ~70 - ~185
tilt = (tilt - 70) * 1.5; // convert to angle in degrees, roughly
pulseWidth2 = (tilt * 9) + minPulse; // convert angle to microseconds

loop_cnt = 0; // reset for
}
loop_cnt++;

}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo2()
{
// pulse the servo again if rhe refresh time (20 ms) have passed:
if (millis() - lastPulse2 >= refreshTime) {
digitalWrite(servoPin2, HIGH); // Turn the motor on
delayMicroseconds(pulseWidth2); // Length of the pulse sets the motor position
digitalWrite(servoPin2, LOW); // Turn the motor off
lastPulse2 = millis(); // save the time of the last pulse
}
}

void checkNunchuck3()
{
if( loop_cnt > 100 ) { // loop()s is every 1msec, this is every 100msec

nunchuck_get_data();
nunchuck_print_data();

float pitch = nunchuck_joyx(); // x-axis, in this case ranges from ~70 - ~185
pitch = (pitch - 70) * 1.5; // convert to angle in degrees, roughly
pulseWidth3 = (pitch * 9) + minPulse; // convert angle to microseconds

loop_cnt = 0; // reset for
}
loop_cnt++;

}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo3()
{
// pulse the servo again if rhe refresh time (20 ms) have passed:
if (millis() - lastPulse3 >= refreshTime) {
digitalWrite(servoPin3, HIGH); // Turn the motor on
delayMicroseconds(pulseWidth3); // Length of the pulse sets the motor position
digitalWrite(servoPin3, LOW); // Turn the motor off
lastPulse3 = millis(); // save the time of the last pulse
}
}

void checkNunchuck4()
{
if( loop_cnt > 100 ) { // loop()s is every 1msec, this is every 100msec

nunchuck_get_data();
nunchuck_print_data();

float yaw = nunchuck_joyy(); // y-axis, in this case ranges from ~70 - ~185
yaw = (yaw - 70) * 1.5; // convert to angle in degrees, roughly
pulseWidth4 = (yaw * 9) + minPulse; // convert angle to microseconds

loop_cnt = 0; // reset for
}
loop_cnt++;

}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo4()
{
// pulse the servo again if rhe refresh time (20 ms) have passed:
if (millis() - lastPulse4 >= refreshTime) {
digitalWrite(servoPin4, HIGH); // Turn the motor on
delayMicroseconds(pulseWidth4); // Length of the pulse sets the motor position
digitalWrite(servoPin4, LOW); // Turn the motor off
lastPulse4 = millis(); // save the time of the last pulse
}
}
 
Last edited by a moderator:
Status
Not open for further replies.
Back
Top