#ifndef ROBOT_MATH_HPP #define ROBOT_MATH_HPP #define PI 3.14159265359 #define PIdiv2 PI/2 const float shoulder_and_elbow_length = 12.5; const float shoulder_plus_elbow_length = shoulder_and_elbow_length * 2; const float wrist_length = 19; class Vec2 { public: Vec2(float _x, float _y) : x(_x), y(_y) {} float x,y; }; class Vec4 { public: Vec4(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) {} Vec4 to_rotation(){ float base_angle = atan2(x, y); float wRAD = w * PI / 180; // take the wrist into account Vec2 target_position = Vec2(hypotf(x, y) - sin(wRAD) * wrist_length, -z + cos(wRAD) * wrist_length); /////// shoulder and elbow angles calculations /////// // calculate distance beetween the arm base and the target position and then clamp it to 1 float target_base_distance = hypotf(target_position.x, target_position.y) / shoulder_plus_elbow_length; if (target_base_distance > 1) { target_base_distance = 1; } // set shoulder angle to arm bend angle from distance from target position to base position float shoulder_angle = asin(target_base_distance); // calculate shoulder angle from the shoulder angle before performing another calculation on it float elbow_angle = PI - (shoulder_angle * 2); // add angle beetween the target position and the base position to the shoulder angle shoulder_angle += atan2(target_position.y, target_position.x); ///////// wrist angle calculation /////// float shoulder_plus_elbow_angle = shoulder_angle + elbow_angle; // shoulder angle + elbow angle //Serial.println(shoulder_plus_elbow_angle); //Serial.println(wRAD); float wrist_angle = wRAD - shoulder_plus_elbow_angle; // # target wrist angle - shoulder_plus_elbow_angle so the wrist angle is always fixes to the base rotation return Vec4(base_angle * 180 / PI, shoulder_angle * 180 / PI + 90, elbow_angle * 180 / PI + 90, wrist_angle * 180 / PI + 90); } void print(){ //Serial.println(x); Serial.println(y); Serial.println(z); Serial.println(w); Serial.println("=================="); } float x,y,z,w; }; #endif