FireFly 2011: Arduino Mega + SSC-32, Wii Nunchuk, preset walking sequences
From Electronics\Hexapod\Arduino sketches 2011-2012\hexapod_oud (banner 'Version 3.0').
This commit is contained in:
1 parent
160b6ec36a
commit
fe472bfce9
16 files changed
+1079
No files matched your search
@@ -0,0 +1,28 @@
|
|||||||
|
#include "Data_Manager.h"
|
||||||
|
|
||||||
|
// Raw variable that must be send to the ssc32.
|
||||||
|
int RAW_2_SERVO[18];
|
||||||
|
|
||||||
|
// Angel to converter.
|
||||||
|
int DEG_2_CON[18];
|
||||||
|
|
||||||
|
// Coordinate to iverse kinematics.
|
||||||
|
int COR_2_IK[18];
|
||||||
|
|
||||||
|
// Orbit angles.
|
||||||
|
int ORBIT_X, ORBIT_Y, ORBIT_Z;
|
||||||
|
|
||||||
|
// Hight.
|
||||||
|
int HIGHT;
|
||||||
|
|
||||||
|
// Walk Direction relative from body.
|
||||||
|
int DIR_R_BODY;
|
||||||
|
|
||||||
|
// IK Legnth.
|
||||||
|
int l1, l2;
|
||||||
|
|
||||||
|
// Min and Max for SSC32.
|
||||||
|
int smin[3], smax[3];
|
||||||
|
|
||||||
|
// WalkTime
|
||||||
|
int walktime;
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// Data_Manager.h
|
||||||
|
|
||||||
|
#ifndef DATA_MANAGER
|
||||||
|
#define DATA_MANAGER
|
||||||
|
|
||||||
|
extern int RAW_2_SERVO[18];
|
||||||
|
extern int DEG_2_CON[18];// int
|
||||||
|
extern int COR_2_IK[18];
|
||||||
|
extern int ORBIT_X, ORBIT_Y, ORBIT_Z;
|
||||||
|
extern int HIGHT;
|
||||||
|
extern int DIRECTION;
|
||||||
|
extern int l1, l2;
|
||||||
|
extern int smin[3], smax[3];
|
||||||
|
extern int walktime;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
// Include.
|
||||||
|
#include <math.h>
|
||||||
|
#include "InverseKinemetics.h"
|
||||||
|
#include "SSC32.h"
|
||||||
|
#include "sequnces.h"
|
||||||
|
#include "Orbit.h"
|
||||||
|
#include "Data_Manager.h"
|
||||||
|
|
||||||
|
// Classes.
|
||||||
|
InverseKinemetics ik;
|
||||||
|
SSC32 body;
|
||||||
|
Orbit orbit;
|
||||||
|
|
||||||
|
// Nunchuck.
|
||||||
|
#include "WiiChuck.h"
|
||||||
|
|
||||||
|
#define MAXANGLE 90
|
||||||
|
#define MINANGLE -90
|
||||||
|
|
||||||
|
WiiChuck chuck = WiiChuck();
|
||||||
|
int angleStart, currentAngle;
|
||||||
|
int tillerStart = 100;
|
||||||
|
double angle;
|
||||||
|
|
||||||
|
// Functions.
|
||||||
|
void FireFly()
|
||||||
|
{
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println(" ____ ____ ___ ");
|
||||||
|
Serial.println("/\\ _`\\ __ /\\ _`\\ /\\_ \\ ");
|
||||||
|
Serial.println("\\ \\ \\L\\_\\/\\_\\ _ __ __\\ \\ \\L\\_\\//\\ \\ __ __ ");
|
||||||
|
Serial.println(" \\ \\ _\\/\\/\\ \\/\\`'__\\/'__`\\ \\ _\\/ \\ \\ \\ /\\ \\/\\ \\ ");
|
||||||
|
Serial.println(" \\ \\ \\/ \\ \\ \\ \\ \\//\\ __/\\ \\ \\/ \\_\\ \\_\\ \\ \\_\\ \\ ");
|
||||||
|
Serial.println(" \\ \\_\\ \\ \\_\\ \\_\\\\ \\____\\\\ \\_\\ /\\____\\\\/`____ \\ ");
|
||||||
|
Serial.println(" \\/_/ \\/_/\\/_/ \\/____/ \\/_/ \\/____/ `/___/> \\");
|
||||||
|
Serial.println(" /\\___/");
|
||||||
|
Serial.println(" \\/__/ ");
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println("Version 3.0");
|
||||||
|
delay(800);
|
||||||
|
}
|
||||||
|
|
||||||
|
void warning ()
|
||||||
|
{
|
||||||
|
digitalWrite(13, HIGH);
|
||||||
|
delay(100);
|
||||||
|
digitalWrite(13, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
//#include "WProgram.h"
|
||||||
|
#include "InverseKinemetics.h"
|
||||||
|
|
||||||
|
void InverseKinemetics::RL3 (int i)
|
||||||
|
{
|
||||||
|
l3 = sqrt(pow(abs(COR_2_IK[0+(i*3)]), 2) + pow(abs(COR_2_IK[2+(i*3)]), 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
float InverseKinemetics::ZX (int i)
|
||||||
|
{
|
||||||
|
RL3(i);
|
||||||
|
float temp = degrees(acos((float)COR_2_IK[2+(i*3)] / l3));
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
float InverseKinemetics::TT (int i)
|
||||||
|
{
|
||||||
|
int x = pow(abs(COR_2_IK[0+(i*3)]), 2);
|
||||||
|
int y = pow(abs(COR_2_IK[1+(i*3)]), 2);
|
||||||
|
int z = pow(abs(COR_2_IK[2+(i*3)]), 2);
|
||||||
|
s = sqrt(x + y + z);
|
||||||
|
|
||||||
|
if (s > (l1 + l2) )
|
||||||
|
R[i] = 3;
|
||||||
|
|
||||||
|
float t1 = degrees(acos((pow(s, 2) + pow(COR_2_IK[1+(i*3)], 2) - pow(l3, 2))
|
||||||
|
/ (2 * s * COR_2_IK[1+(i*3)])));
|
||||||
|
|
||||||
|
float t2 = degrees(acos((pow(s, 2) + pow(l1, 2) - pow(l2, 2))
|
||||||
|
/ (2 * s * l1)));
|
||||||
|
|
||||||
|
float temp = (int)t1 + t2;
|
||||||
|
//Serial.print("DEBUG: "); Serial.print(t1); Serial.print(", "); Serial.print(t2); Serial.print(", "); Serial.println(temp);
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
int InverseKinemetics::LL ()
|
||||||
|
{
|
||||||
|
int temp = degrees(acos((float)(pow(l1, 2) + pow(l2, 2) - pow(s, 2)) / (2 * l1 * l2)));
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InverseKinemetics::setleg (int i)
|
||||||
|
{
|
||||||
|
Serial.print("Set Leg ");
|
||||||
|
Serial.println(i);
|
||||||
|
if (i >= 3)
|
||||||
|
{
|
||||||
|
//Error_Coordinate(i);
|
||||||
|
DEG_2_CON[0+(i*3)] = 180 - ZX(i);
|
||||||
|
DEG_2_CON[1+(i*3)] = 180 - TT(i);
|
||||||
|
DEG_2_CON[2+(i*3)] = LL();
|
||||||
|
Error_Angle(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Error_Coordinate(i);
|
||||||
|
DEG_2_CON[0+(i*3)] = ZX(i);
|
||||||
|
DEG_2_CON[1+(i*3)] = TT(i);
|
||||||
|
DEG_2_CON[2+(i*3)] = 180 - LL();
|
||||||
|
Error_Angle(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InverseKinemetics::setlegs ()
|
||||||
|
{
|
||||||
|
for (int i=0; i<6; i++)
|
||||||
|
{
|
||||||
|
setleg(i);
|
||||||
|
}
|
||||||
|
for (int i=0; i<6; i++)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
Serial.print(", ");
|
||||||
|
else
|
||||||
|
Serial.print("Cor: ");
|
||||||
|
Serial.print(COR_2_IK[0+(i*3)]);
|
||||||
|
Serial.print(", ");
|
||||||
|
Serial.print(COR_2_IK[1+(i*3)]);
|
||||||
|
Serial.print(", ");
|
||||||
|
Serial.print(COR_2_IK[2+(i*3)]);
|
||||||
|
}
|
||||||
|
Serial.println(";");
|
||||||
|
}
|
||||||
|
|
||||||
|
void InverseKinemetics::Error_Angle (int i)
|
||||||
|
{
|
||||||
|
for (int i2=0; i2<3; i2++)
|
||||||
|
R[i2+(i*3)] = 0;
|
||||||
|
if (DEG_2_CON[0+(i*3)] < 0)
|
||||||
|
R[0+(i*3)] = 1;
|
||||||
|
if (DEG_2_CON[0+(i*3)] > 180)
|
||||||
|
R[0+(i*3)] = 2;
|
||||||
|
if (DEG_2_CON[1+(i*3)] < 0)
|
||||||
|
R[1+(i*3)] = 1;
|
||||||
|
if (DEG_2_CON[1+(i*3)] > 180)
|
||||||
|
R[1+(i*3)] = 2;
|
||||||
|
if (DEG_2_CON[2+(i*3)] < 0)
|
||||||
|
R[2+(i*3)] = 1;
|
||||||
|
if (DEG_2_CON[2+(i*3)] > 180)
|
||||||
|
R[2+(i*3)] = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InverseKinemetics::Error_Coordinate (int i)
|
||||||
|
{
|
||||||
|
Ra[i] = 0;
|
||||||
|
float temp = sqrt(pow(COR_2_IK[0+(i*3)], 2) + pow(COR_2_IK[1+(i*3)], 2) + pow(COR_2_IK[2+(i*3)], 2));
|
||||||
|
if (temp <= 5) {
|
||||||
|
Ra[i] = 1;
|
||||||
|
}
|
||||||
|
if (temp > l1 + l2) {
|
||||||
|
Ra[i] = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int InverseKinemetics::CheckForErrorCor()
|
||||||
|
{
|
||||||
|
for (int i=1; i<19; i++)
|
||||||
|
if (R[i-1]!=0)
|
||||||
|
return i;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
String InverseKinemetics::CheckForErrorCor_print()
|
||||||
|
{
|
||||||
|
String temp = "Error Coordinate: ";
|
||||||
|
for (int i=0; i<18; i++)
|
||||||
|
{
|
||||||
|
temp = temp + (int)DEG_2_CON[i] + ", ";
|
||||||
|
}
|
||||||
|
temp = temp + "\nCheckForErrorCor returnd: " + CheckForErrorCor();
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
int InverseKinemetics::CheckForErrorAng()
|
||||||
|
{
|
||||||
|
for (int i=0; i<6; i++)
|
||||||
|
if (Ra[i]!=0)
|
||||||
|
return i;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#ifndef InverseKinemetics_H
|
||||||
|
#define InverseKinemetics_H
|
||||||
|
|
||||||
|
#include "WProgram.h"
|
||||||
|
#include <math.h>
|
||||||
|
#include "Data_Manager.h"
|
||||||
|
|
||||||
|
class InverseKinemetics
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
void RL3(int i);
|
||||||
|
float ZX (int i);
|
||||||
|
float TT (int i);
|
||||||
|
int LL ();
|
||||||
|
void setlegs ();
|
||||||
|
void setleg (int i);
|
||||||
|
|
||||||
|
/* // Input
|
||||||
|
void setLeftFrontLeg (int ix, int iy, int iz); // clockwise, t3=clockwise, t3=counterclockwise
|
||||||
|
void setLeftMiddleLeg (int ix, int iy, int iz); // clockwise, t3=clockwise, t3=counterclockwise
|
||||||
|
void setLeftBackLeg (int ix, int iy, int iz); // clockwise, t3=clockwise, t3=counterclockwise
|
||||||
|
void setRightFrontLeg (int ix, int iy, int iz); // counterclockwise, t3=counterclockwise, t3=clockwise
|
||||||
|
void setRightMiddleLeg(int ix, int iy, int iz); // counterclockwise, t3=counterclockwise, t3=clockwise
|
||||||
|
void setRightBackLeg (int ix, int iy, int iz); // counterclockwise, t3=counterclockwise, t3=clockwise*/
|
||||||
|
|
||||||
|
// 0 | 3
|
||||||
|
// 1 | 4
|
||||||
|
// 2 | 5
|
||||||
|
|
||||||
|
//
|
||||||
|
void Error_Angle (int i);
|
||||||
|
void Error_Coordinate (int i);
|
||||||
|
|
||||||
|
int CheckForErrorCor();
|
||||||
|
String CheckForErrorCor_print();
|
||||||
|
int CheckForErrorAng();
|
||||||
|
|
||||||
|
// Variable's
|
||||||
|
int s;
|
||||||
|
float l3;
|
||||||
|
byte R[18];
|
||||||
|
byte Ra[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
// Orbit.cpp
|
||||||
|
|
||||||
|
#include "Orbit.h"
|
||||||
|
|
||||||
|
void Orbit::getData(int iy[6], int ix[6], int iz[6])
|
||||||
|
{
|
||||||
|
for (int i=0; i<6; i++)
|
||||||
|
{
|
||||||
|
x[i] = ix[i];
|
||||||
|
y[i] = iy[i];
|
||||||
|
z[i] = iz[i];
|
||||||
|
}
|
||||||
|
lx[0] = 5;
|
||||||
|
lx[1] = 7;
|
||||||
|
lx[2] = 5;
|
||||||
|
lx[3] = 5;
|
||||||
|
lx[4] = 7;
|
||||||
|
lx[5] = 5;
|
||||||
|
ly[0] = 10;
|
||||||
|
ly[1] = 0;
|
||||||
|
ly[2] = 10;
|
||||||
|
ly[3] = 10;
|
||||||
|
ly[4] = 0;
|
||||||
|
ly[5] = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Orbit::getAngle (int ix, int iy)
|
||||||
|
{
|
||||||
|
oP = ix;
|
||||||
|
o2P = iy;
|
||||||
|
oN = 180 - ix;
|
||||||
|
o2N = 180 - iy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Orbit::calculate()
|
||||||
|
{
|
||||||
|
// X Size.
|
||||||
|
// Right side.
|
||||||
|
for (int i=3; i<6; i++)
|
||||||
|
{
|
||||||
|
float l1 = sqrt(pow(x[i], 2) + pow(y[i], 2));
|
||||||
|
float o1 = degrees(atan(y[i] / x[i]));
|
||||||
|
float o2 = oP - o1;
|
||||||
|
Ny[i] = sin(radians(o2)) * l1;
|
||||||
|
Nx[i] = (cos(radians(o2)) * l1) - lx[i];
|
||||||
|
Nz[i] = z[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Left size;
|
||||||
|
for (int i=0; i<4; i++)
|
||||||
|
{
|
||||||
|
float l1 = sqrt(pow(x[i], 2) + pow(y[i], 2));
|
||||||
|
float o1 = degrees(atan(y[i] / x[i]));
|
||||||
|
float o2 = oN - o1;
|
||||||
|
Ny[i] = sin(radians(o2)) * l1;
|
||||||
|
Nx[i] = (cos(radians(o2)) * l1) - lx[i];
|
||||||
|
Nz[i] = z[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Y Size.
|
||||||
|
// Right side.
|
||||||
|
/*for (int i=3; i<6; i++) WRong
|
||||||
|
{
|
||||||
|
float l1 = sqrt(pow(x[i], 2) + pow(y[i], 2));
|
||||||
|
float o1 = degrees(atan(y[i] / x[i]));
|
||||||
|
float o2 = o2P - o1;
|
||||||
|
Ny[i] = sin(radians(o2)) * l1;
|
||||||
|
Nx[i] = (cos(radians(o2)) * l1) - lx[i];
|
||||||
|
Nz[i] = z[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Left size;
|
||||||
|
for (int i=0; i<4; i++) WRong
|
||||||
|
{
|
||||||
|
float l1 = sqrt(pow(x[i], 2) + pow(y[i], 2));
|
||||||
|
float o1 = degrees(atan(y[i] / x[i]));
|
||||||
|
float o2 = o2N - o1;
|
||||||
|
Ny[i] = sin(radians(o2)) * l1;
|
||||||
|
Nx[i] = (cos(radians(o2)) * l1) - lx[i];
|
||||||
|
Nz[i] = z[i];
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// Orbit.h
|
||||||
|
|
||||||
|
#ifndef Orbit_H
|
||||||
|
#define Orbit_H
|
||||||
|
|
||||||
|
#include "WProgram.h"
|
||||||
|
|
||||||
|
class Orbit
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void getData(int ix[6], int iy[6], int iz[6]);
|
||||||
|
void getAngle (int ix, int iy);
|
||||||
|
|
||||||
|
void calculate();
|
||||||
|
|
||||||
|
int x[6], y[6], z[6];
|
||||||
|
int Nx[6], Ny[6], Nz[6];
|
||||||
|
int oP, o2P, oN, o2N;
|
||||||
|
int lx[6], ly[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// Rotation.cpp
|
||||||
|
|
||||||
|
#include "Rotation.h"
|
||||||
|
|
||||||
|
void Rotation::getData(int ix[6], int iy[6], int iz[6])
|
||||||
|
{
|
||||||
|
for (int i=0; i<6; i++)
|
||||||
|
{
|
||||||
|
x[i] = ix[i];
|
||||||
|
y[i] = iy[i];
|
||||||
|
z[i] = iz[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int NewX, NewY;
|
||||||
|
void rotate (int x, int y, int angel)
|
||||||
|
{
|
||||||
|
NewY = x * sin(radians(angel)) + y * cos(radians(angel));
|
||||||
|
NewX = x * cos(radians(angel)) - y * sin(radians(angel));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// Rotation.h
|
||||||
|
|
||||||
|
#ifndef Rotation_H
|
||||||
|
#define Rotation_H
|
||||||
|
|
||||||
|
#include "WProgram.h"
|
||||||
|
|
||||||
|
class Rotation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void getData(int ix[6], int iy[6], int iz[6]);
|
||||||
|
|
||||||
|
int x[6], y[6], z[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
#include "SSC32.h"
|
||||||
|
|
||||||
|
void SSC32::setup()
|
||||||
|
{
|
||||||
|
Serial1.begin(38400);
|
||||||
|
Serial.begin(38400);
|
||||||
|
time = 0;
|
||||||
|
walktime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSC32::MoveHead (int angel_from_mid)
|
||||||
|
{
|
||||||
|
Serial1.print(" #");
|
||||||
|
Serial1.print(9);
|
||||||
|
Serial1.print(" P");
|
||||||
|
Serial1.print(ConverttoMS((90 + angel_from_mid), smin[0], smax[0]));
|
||||||
|
Serial1.print(" T");
|
||||||
|
Serial1.println(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSC32::Render()
|
||||||
|
{
|
||||||
|
for (int i=0; i<6; i++)
|
||||||
|
{
|
||||||
|
RAW_2_SERVO[0+(i*3)] = ConverttoMS(DEG_2_CON[0+(i*3)], smin[0], smax[0]);
|
||||||
|
RAW_2_SERVO[1+(i*3)] = ConverttoMS(DEG_2_CON[1+(i*3)], smin[1], smax[1]);
|
||||||
|
RAW_2_SERVO[2+(i*3)] = ConverttoMS(DEG_2_CON[2+(i*3)], smin[2], smax[2]);
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
Serial.print(", ");
|
||||||
|
else
|
||||||
|
Serial.print("Ang: ");
|
||||||
|
|
||||||
|
Serial.print(DEG_2_CON[0+(i*3)]);
|
||||||
|
Serial.print(", ");
|
||||||
|
Serial.print(DEG_2_CON[1+(i*3)]);
|
||||||
|
Serial.print(", ");
|
||||||
|
Serial.print(DEG_2_CON[2+(i*3)]);
|
||||||
|
}
|
||||||
|
Serial.println(";");
|
||||||
|
}
|
||||||
|
|
||||||
|
int SSC32::ConverttoMS(int i, int low, int high)
|
||||||
|
{
|
||||||
|
int tmp = ( i * ( ( high - low ) / 180 ) );
|
||||||
|
return low + tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSC32::toServos ()
|
||||||
|
{
|
||||||
|
// puss to servos
|
||||||
|
|
||||||
|
// var. SSC32.
|
||||||
|
// 0 | 3 // 16 | 0
|
||||||
|
// 1 | 4 // | | |
|
||||||
|
// 2 | 5 // 24 | 8
|
||||||
|
|
||||||
|
for (int i=0; i<9; i++)
|
||||||
|
{
|
||||||
|
Serial1.print(" #");
|
||||||
|
Serial1.print(16+i);// 18 22
|
||||||
|
Serial1.print(" P");
|
||||||
|
Serial1.print(RAW_2_SERVO[9+i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<9; i++)
|
||||||
|
{
|
||||||
|
Serial1.print(" #");
|
||||||
|
Serial1.print(i);
|
||||||
|
Serial1.print(" P");
|
||||||
|
Serial1.print(RAW_2_SERVO[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial1.print(" T");
|
||||||
|
Serial1.println(walktime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// SSC32.h
|
||||||
|
|
||||||
|
#ifndef SSC32_H
|
||||||
|
#define SSC32_H
|
||||||
|
|
||||||
|
#include "WProgram.h"
|
||||||
|
#include "Data_Manager.h"
|
||||||
|
|
||||||
|
class SSC32
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void setup();
|
||||||
|
|
||||||
|
void Render();
|
||||||
|
void toServos ();
|
||||||
|
void MoveHead (int angel_from_mid);
|
||||||
|
|
||||||
|
int ConverttoMS(int i, int low, int high);
|
||||||
|
|
||||||
|
// 0 | 3
|
||||||
|
// 1 | 4
|
||||||
|
// 2 | 5
|
||||||
|
|
||||||
|
int time;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,210 @@
|
|||||||
|
/*
|
||||||
|
* Nunchuck -- Use a Wii Nunchuck
|
||||||
|
* Tim Hirzel http://www.growdown.com
|
||||||
|
*
|
||||||
|
notes on Wii Nunchuck Behavior.
|
||||||
|
This library provides an improved derivation of rotation angles from the nunchuck accelerometer data.
|
||||||
|
The biggest different over existing libraries (that I know of ) is the full 360 degrees of Roll data
|
||||||
|
from teh combination of the x and z axis accelerometer data using the math library atan2.
|
||||||
|
|
||||||
|
It is accurate with 360 degrees of roll (rotation around axis coming out of the c button, the front of the wii),
|
||||||
|
and about 180 degrees of pitch (rotation about the axis coming out of the side of the wii). (read more below)
|
||||||
|
|
||||||
|
In terms of mapping the wii position to angles, its important to note that while the Nunchuck
|
||||||
|
sense Pitch, and Roll, it does not sense Yaw, or the compass direction. This creates an important
|
||||||
|
disparity where the nunchuck only works within one hemisphere. At a result, when the pitch values are
|
||||||
|
less than about 10, and greater than about 170, the Roll data gets very unstable. essentially, the roll
|
||||||
|
data flips over 180 degrees very quickly. To understand this property better, rotate the wii around the
|
||||||
|
axis of the joystick. You see the sensor data stays constant (with noise). Because of this, it cant know
|
||||||
|
the difference between arriving upside via 180 degree Roll, or 180 degree pitch. It just assumes its always
|
||||||
|
180 roll.
|
||||||
|
|
||||||
|
|
||||||
|
*
|
||||||
|
* This file is an adaptation of the code by these authors:
|
||||||
|
* Tod E. Kurt, http://todbot.com/blog/
|
||||||
|
*
|
||||||
|
* The Wii Nunchuck reading code is taken from Windmeadow Labs
|
||||||
|
* http://www.windmeadow.com/node/42
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WiiChuck_h
|
||||||
|
#define WiiChuck_h
|
||||||
|
|
||||||
|
#include "WProgram.h"
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
// these may need to be adjusted for each nunchuck for calibration
|
||||||
|
#define ZEROX 510
|
||||||
|
#define ZEROY 490
|
||||||
|
#define ZEROZ 460
|
||||||
|
#define RADIUS 180 // probably pretty universal
|
||||||
|
|
||||||
|
#define DEFAULT_ZERO_JOY_X 124
|
||||||
|
#define DEFAULT_ZERO_JOY_Y 132
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class WiiChuck {
|
||||||
|
private:
|
||||||
|
byte cnt;
|
||||||
|
uint8_t status[6]; // array to store wiichuck output
|
||||||
|
byte averageCounter;
|
||||||
|
//int accelArray[3][AVERAGE_N]; // X,Y,Z
|
||||||
|
int i;
|
||||||
|
int total;
|
||||||
|
uint8_t zeroJoyX; // these are about where mine are
|
||||||
|
uint8_t zeroJoyY; // use calibrateJoy when the stick is at zero to correct
|
||||||
|
int lastJoyX;
|
||||||
|
int lastJoyY;
|
||||||
|
int angles[3];
|
||||||
|
|
||||||
|
boolean lastZ, lastC;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
byte joyX;
|
||||||
|
byte joyY;
|
||||||
|
boolean buttonZ;
|
||||||
|
boolean buttonC;
|
||||||
|
void begin()
|
||||||
|
{
|
||||||
|
Wire.begin();
|
||||||
|
cnt = 0;
|
||||||
|
averageCounter = 0;
|
||||||
|
Wire.beginTransmission (0x52); // transmit to device 0x52
|
||||||
|
Wire.send (0x40); // sends memory address
|
||||||
|
Wire.send (0x00); // sends memory address
|
||||||
|
Wire.endTransmission (); // stop transmitting
|
||||||
|
update();
|
||||||
|
for (i = 0; i<3;i++) {
|
||||||
|
angles[i] = 0;
|
||||||
|
}
|
||||||
|
zeroJoyX = DEFAULT_ZERO_JOY_X;
|
||||||
|
zeroJoyY = DEFAULT_ZERO_JOY_Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void calibrateJoy() {
|
||||||
|
zeroJoyX = joyX;
|
||||||
|
zeroJoyY = joyY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() {
|
||||||
|
|
||||||
|
Wire.requestFrom (0x52, 6); // request data from nunchuck
|
||||||
|
while (Wire.available ()) {
|
||||||
|
// receive byte as an integer
|
||||||
|
status[cnt] = _nunchuk_decode_byte (Wire.receive()); //
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
if (cnt > 5) {
|
||||||
|
lastZ = buttonZ;
|
||||||
|
lastC = buttonC;
|
||||||
|
lastJoyX = readJoyX();
|
||||||
|
lastJoyY = readJoyY();
|
||||||
|
//averageCounter ++;
|
||||||
|
//if (averageCounter >= AVERAGE_N)
|
||||||
|
// averageCounter = 0;
|
||||||
|
|
||||||
|
cnt = 0;
|
||||||
|
joyX = (status[0]);
|
||||||
|
joyY = (status[1]);
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
//accelArray[i][averageCounter] = ((int)status[i+2] << 2) + ((status[5] & (B00000011 << ((i+1)*2) ) >> ((i+1)*2)));
|
||||||
|
angles[i] = (status[i+2] << 2) + ((status[5] & (B00000011 << ((i+1)*2) ) >> ((i+1)*2)));
|
||||||
|
|
||||||
|
//accelYArray[averageCounter] = ((int)status[3] << 2) + ((status[5] & B00110000) >> 4);
|
||||||
|
//accelZArray[averageCounter] = ((int)status[4] << 2) + ((status[5] & B11000000) >> 6);
|
||||||
|
|
||||||
|
buttonZ = !( status[5] & B00000001);
|
||||||
|
buttonC = !((status[5] & B00000010) >> 1);
|
||||||
|
_send_zero(); // send the request for next bytes
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// UNCOMMENT FOR DEBUGGING
|
||||||
|
//byte * getStatus() {
|
||||||
|
// return status;
|
||||||
|
//}
|
||||||
|
|
||||||
|
float readAccelX() {
|
||||||
|
// total = 0; // accelArray[xyz][averageCounter] * FAST_WEIGHT;
|
||||||
|
return (float)angles[0] - ZEROX;
|
||||||
|
}
|
||||||
|
float readAccelY() {
|
||||||
|
// total = 0; // accelArray[xyz][averageCounter] * FAST_WEIGHT;
|
||||||
|
return (float)angles[1] - ZEROY;
|
||||||
|
}
|
||||||
|
float readAccelZ() {
|
||||||
|
// total = 0; // accelArray[xyz][averageCounter] * FAST_WEIGHT;
|
||||||
|
return (float)angles[2] - ZEROZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean zPressed() {
|
||||||
|
return (buttonZ && ! lastZ);
|
||||||
|
}
|
||||||
|
boolean cPressed() {
|
||||||
|
return (buttonC && ! lastC);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for using the joystick like a directional button
|
||||||
|
boolean rightJoy(int thresh=60) {
|
||||||
|
return (readJoyX() > thresh and lastJoyX <= thresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for using the joystick like a directional button
|
||||||
|
boolean leftJoy(int thresh=60) {
|
||||||
|
return (readJoyX() < -thresh and lastJoyX >= -thresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int readJoyX() {
|
||||||
|
return (int) joyX - zeroJoyX;
|
||||||
|
}
|
||||||
|
|
||||||
|
int readJoyY() {
|
||||||
|
return (int)joyY - zeroJoyY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// R, the radius, generally hovers around 210 (at least it does with mine)
|
||||||
|
// int R() {
|
||||||
|
// return sqrt(readAccelX() * readAccelX() +readAccelY() * readAccelY() + readAccelZ() * readAccelZ());
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// returns roll degrees
|
||||||
|
int readRoll() {
|
||||||
|
return (int)(atan2(readAccelX(),readAccelZ())/ M_PI * 180.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns pitch in degrees
|
||||||
|
int readPitch() {
|
||||||
|
return (int) (acos(readAccelY()/RADIUS)/ M_PI * 180.0); // optionally swap 'RADIUS' for 'R()'
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
byte _nunchuk_decode_byte (byte x)
|
||||||
|
{
|
||||||
|
x = (x ^ 0x17) + 0x17;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _send_zero()
|
||||||
|
{
|
||||||
|
Wire.beginTransmission (0x52); // transmit to device 0x52
|
||||||
|
Wire.send (0x00); // sends one byte
|
||||||
|
Wire.endTransmission (); // stop transmitting
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// atan2.cpp
|
||||||
|
|
||||||
|
#include "atan2.h"
|
||||||
|
|
||||||
|
void joy::JoyToDegAndDis (int x, int y)
|
||||||
|
{
|
||||||
|
deg = !(90 + degrees(atan2(y, x)));
|
||||||
|
distance = sqrt(y^2 + x^2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int joy::JoyToDeg (int x, int y)
|
||||||
|
{ // watchout 90 + does not work good
|
||||||
|
return !(degrees(atan2(y, x)));
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// atan2.h
|
||||||
|
|
||||||
|
#ifndef joy_H
|
||||||
|
#define joy_H
|
||||||
|
|
||||||
|
#include "WProgram.h"
|
||||||
|
|
||||||
|
class joy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void JoyToDegAndDis (int x, int y);
|
||||||
|
int JoyToDeg (int x, int y);
|
||||||
|
|
||||||
|
int deg, distance;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
// Hexapod FireFly
|
||||||
|
|
||||||
|
#include "Header.h"
|
||||||
|
#include "Wire.h" // Just dont work's, if you put it in the Header file.
|
||||||
|
|
||||||
|
// Setup.
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
chuck.begin();
|
||||||
|
chuck.update();
|
||||||
|
smin[0] = 600;
|
||||||
|
smin[1] = 960;
|
||||||
|
smin[2] = 600;
|
||||||
|
smax[0] = 2400;
|
||||||
|
smax[1] = 2100;
|
||||||
|
smax[2] = 2400;
|
||||||
|
l1 = 10;
|
||||||
|
l2 = 15;
|
||||||
|
pinMode(13, OUTPUT); // Led L
|
||||||
|
Serial.begin(38400);
|
||||||
|
body.setup();
|
||||||
|
FireFly();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Position.
|
||||||
|
int Position=1;
|
||||||
|
int PosMax=15;
|
||||||
|
int BeginPos=0;
|
||||||
|
int Directory=0;
|
||||||
|
|
||||||
|
void UpdatePosition(int i=0)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
if ((Position < PosMax) && (Directory == 0))
|
||||||
|
Position++;
|
||||||
|
else if (Directory == 0)
|
||||||
|
Directory=1;
|
||||||
|
else if ((Position > 1) && (Directory == 1))
|
||||||
|
Position--;
|
||||||
|
else
|
||||||
|
Directory=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Position < PosMax)
|
||||||
|
Position++;
|
||||||
|
else
|
||||||
|
Position = BeginPos;
|
||||||
|
|
||||||
|
if (Directory == 1)
|
||||||
|
{
|
||||||
|
Directory = 2;
|
||||||
|
Position = BeginPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==============================================/
|
||||||
|
|
||||||
|
Go Use Class::operator=, To give Data From IK Class To Rotation or SSC32 Class.
|
||||||
|
|
||||||
|
/==============================================*/
|
||||||
|
|
||||||
|
// Variables.
|
||||||
|
double past = millis();
|
||||||
|
int Watchdog=0;
|
||||||
|
|
||||||
|
// Main loop.
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
if (millis() < past) // to handle te exception of 50 day overflow of millis()
|
||||||
|
past = millis();
|
||||||
|
|
||||||
|
while ( ((millis() - past) < walktime) || (Watchdog == 0))
|
||||||
|
{
|
||||||
|
/* chuck.update();
|
||||||
|
ojx = chuck.readJoyX();
|
||||||
|
ojy = chuck.readJoyY();
|
||||||
|
oax = chuck.readAccelX();
|
||||||
|
oay = chuck.readAccelY();
|
||||||
|
|
||||||
|
// Mode Head Servo.
|
||||||
|
body.MoveHead(chuck.readRoll());*/
|
||||||
|
|
||||||
|
if (Watchdog == 0)
|
||||||
|
{
|
||||||
|
walktime = 300;
|
||||||
|
|
||||||
|
if (Directory==0)
|
||||||
|
{
|
||||||
|
UpdatePosition();
|
||||||
|
|
||||||
|
for (int i=0; i<6; i++)
|
||||||
|
{
|
||||||
|
COR_2_IK[0+(i*3)] = 10; //x
|
||||||
|
COR_2_IK[1+(i*3)] = Position; //y
|
||||||
|
COR_2_IK[2+(i*3)] = 0; //z
|
||||||
|
}
|
||||||
|
COR_2_IK[2+(0*3)] = -10;// x side body
|
||||||
|
COR_2_IK[2+(2*3)] = 10;///
|
||||||
|
COR_2_IK[2+(3*3)] = -10;//
|
||||||
|
COR_2_IK[2+(5*3)] = 10;///
|
||||||
|
COR_2_IK[0+(1*3)] = 15;// z side body
|
||||||
|
COR_2_IK[0+(4*3)] = 15;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PosMax = 7;
|
||||||
|
UpdatePosition(1);
|
||||||
|
for (int i2=0; i2<18; i2++)
|
||||||
|
{
|
||||||
|
COR_2_IK[i2] = TriPoD[Position][i2];
|
||||||
|
COR_2_IK[i2] = TriPoD[Position][i2];
|
||||||
|
}
|
||||||
|
for(int i=0; i<6; i++)
|
||||||
|
{
|
||||||
|
// zij, laag, achter
|
||||||
|
// 10, 15, -10, 15, 15, 0, 10, 15, 10, 10, 15, -10, 15, 15, 0, 10, 15, 10;
|
||||||
|
int cor[6] = { -5, 0, 5, -5, 0, 5 };
|
||||||
|
COR_2_IK[2+(i*3)] += cor[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* orbit.getAngle(90 + (chuck.readRoll()/3), 90);// 90 + (chuck.readPitch()/3));
|
||||||
|
orbit.getData(x, y, z);
|
||||||
|
orbit.calculate();*/
|
||||||
|
|
||||||
|
// x, y, z
|
||||||
|
// x, z is above the leg, z is depth
|
||||||
|
// y, l3 is side leg, y is height
|
||||||
|
ik.setlegs();
|
||||||
|
body.Render();
|
||||||
|
|
||||||
|
Serial.println("Done Rendering");
|
||||||
|
/*if (ik.CheckForErrorCor() != 0)
|
||||||
|
{
|
||||||
|
warning();
|
||||||
|
Serial.println("Coordinate Error. ");
|
||||||
|
Serial.println(ik.CheckForErrorCor_print());
|
||||||
|
}
|
||||||
|
else*/
|
||||||
|
Watchdog = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
past = millis(); // gifs an overflow after 50 day run.
|
||||||
|
Serial.println("Out of loop");
|
||||||
|
|
||||||
|
if (Watchdog == 1)
|
||||||
|
{
|
||||||
|
if (ik.CheckForErrorAng() == 0) // check if there is no error.
|
||||||
|
{
|
||||||
|
Serial.println("Sending");
|
||||||
|
body.toServos();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
warning();
|
||||||
|
Serial.println("Axis Error.");
|
||||||
|
}
|
||||||
|
Watchdog = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// sequnces
|
||||||
|
|
||||||
|
// Hexapod seqencer.
|
||||||
|
int TriPoD_Size = 8;
|
||||||
|
// zij, laag, achter
|
||||||
|
// 15, 15, -15, 15, 15, 0, 15, 15, 15, 15, 15, -15, 15, 15, 0, 15, 15, 15;
|
||||||
|
int TriPoD[8][18] = {
|
||||||
|
{// -15 is voor
|
||||||
|
15, 2, 0, 15, 15, 0, 15, 2, 0, 15, 15, 0,15, 2, 0, 15, 15, 0 }//miden*hoog, miden*laag
|
||||||
|
,
|
||||||
|
{
|
||||||
|
15, 2, -2, 15, 15, 2, 15, 2, -2, 15, 15, 2,15, 2, -2, 15, 15, 2 }// voor*hoog, achter*laag
|
||||||
|
,
|
||||||
|
{
|
||||||
|
15, 15, -2, 15, 15, 2, 15, 15, -2, 15, 15, 2,15, 15, -2, 15, 15, 2 }// laag, niks
|
||||||
|
,
|
||||||
|
{
|
||||||
|
15, 15, -2, 15, 2, 2, 15, 15, -2, 15, 2, 2,15, 15, -2, 15, 2, 2 }// niks, hoog
|
||||||
|
,
|
||||||
|
{
|
||||||
|
15, 15, 0, 15, 2, 0, 15, 15, 0, 15, 2, 0,15, 15, 0, 15, 2, 0 }//midden*laag, miden*hoog
|
||||||
|
,
|
||||||
|
{
|
||||||
|
15, 15, 2, 15, 2, -2, 15, 15, 2, 15, 2, -2,15, 15, 2, 15, 2, -2 }//voor-laag, achter/hoog
|
||||||
|
,
|
||||||
|
{
|
||||||
|
15, 15, 2, 15, 15, -2, 15, 15, 2, 15, 15, -2,15, 15, 2, 15, 15, -2 }// niks, laag
|
||||||
|
,
|
||||||
|
{
|
||||||
|
15, 2, 2, 15, 15, -2, 15, 2, 2, 15, 15, -2,15, 2, 2, 15, 15, -2 }// hoog, niks
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in new issue
Block a user