Go Down

Topic: successful 2d spider leg experiment and code (Read 693 times) previous topic - next topic

tsmspace

Hello.
I want to share my successful spider leg experiment. I'm sure I didn't make enough notes in the code, but here is a brief description. The leg is two cardboard pieces attached to 2 servos. There is a hip servo and a knee servo, to move the leg in 2 dimensions. As there is no rotation, the x,y axis is vertical, not horizontal, and traditional 3d z is instead y.

On my experiment, the servos are positioned so that the hip degrees are 0 degrees points at the ground, 180 degrees points up, and the knee degrees are 0 degrees points to the leg, and 180 degrees extends the leg fully. Because 0 degrees is pointing to ground on the hip, the y axis is inverted such that to enter a y coordinate below the hip, the user must enter a coordinate of positive y value, and to place the foot above the hip, the user must enter a negative value.

0,0 is the hip servo rotation point.

The code is incomplete, lacking a way to change the x,y coordinates without reloading the program, so the move the leg the user must change the x,y coordinates and the re-upload to the arduino. This is, however, my first successful inverse kinematics experiment.

My next plan is to use potentiometers or a joystick to set the x,y coordinates of the foot. using potentiometers the values of the potentiometers would be mapped to an x,y range, where using the joystick the potentiometers of the joystick would be set so that pointing the joystick causes the x,y coordinates to change progressively at a rate set by the amount of deflection on the stick. so the speed of the x,y coordinate change is controlled by the joystick, as well as the direction of change.

My end goal is to configure a quadruped such that each foot can be selected, and the height of the selected foot is joystick controlled, with the lateral motion controlled by another joystick, such that the foot is raised by one stick, and moved laterally by another stick, with kinematics that automatically center the weight of the quadruped over the 3 feet that are not selected once the foot IS selected, and such that as the foot is extended, all other leg servos move to compensate and maintain a center of balance and moderate leg angle. The purpose of this control method is to climb obstacles manually.

Code: [Select]


//servo leg experiment. 2 servos moving on a 2 dimensional x,y coordinate plane. hip servo at 0,0
//hip servo oriented such that 0 degrees is straight downward, and 180 is straight upward
//knee servo oriented so that 0 is directly toward femur, and that 180 is directly away from tibia (so 180 fully extends the leg)
//my model is backward, with the leg extending to my left, so I input negative values and it seems to want to work
//there are still problems with this code, the solutions it may pick may not be within the range of motion of the servos.
//all measurements are in milimeters.
//open serial monitor to see angle B then angle A, B is hip angle so printed first

#include <Servo.h>
#include <math.h>

Servo hip;
Servo knee;

int femur = 100;
int tibia = 90;


void setup() {
  // put your setup code here, to run once:
hip.attach(9);
knee.attach(10);
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
int x = -100; //change this value to assign a new desired x coordinate, and re-upload program
int y = 30; //change this value to assign a new desired y coordinate, and re-upload program.
//assuming servo hip is oriented, 0 straight down, 180 straight up, y is inverted, so -y is above the x axis
 float L = sqrt((x*x)+(y*y));
 float A = acos(((femur*femur)+(tibia*tibia)-(L*L))/(2*femur*tibia));//outputs number in radians as A
 float B = acos(((femur*femur)+(L*L)-(tibia*tibia))/(2*femur*L))+acos(((L*L)+(y*y)-(x*x))/(2*L*y));//outputs number in radians as B
Serial.print(degrees(B));//converts radians to degrees
Serial.print("    ");
Serial.println(degrees(A));//converts radians to degrees
hip.write(degrees(B));//converts radians to degrees
knee.write(degrees(A));//converts radians to degrees
delay(50);
}

Go Up