⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kinecalc.cc

📁 机器人仿真软件
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* *  Player - One Hell of a Robot Server *  Copyright (C) 2000 *     Brian Gerkey, Kasper Stoy, Richard Vaughan, & Andrew Howard * * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * *//*  Kinematics calculator implementation based on the analytical method by *  Gan et al. See: *  J.Q. Gan, E. Oyama, E.M. Rosales, and H. Hu, "A complete analytical *  solution to the inverse kinematics of the Pioneer 2 robotic arm," *  Robotica, vol.23, no.1, pp.123-129, 2005. */#include <libplayercore/playercommon.h>#include "kinecalc.h"#include <math.h>#include <stdio.h>KineCalc::KineCalc (void){  link1 = 0.06875f;  link2 = 0.16f;  link3 = 0.0f;  link4 = 0.13775f;  link5 = 0.11321f;  endEffector.p.x = 0.0f; endEffector.p.y = 0.0f; endEffector.p.z = 0.0f;  endEffector.n.x = 0.0f; endEffector.n.y = 0.0f; endEffector.n.z = 0.0f;  endEffector.o.x = 0.0f; endEffector.o.y = -1.0f; endEffector.o.z = 1.0f;  endEffector.a.x = 1.0f; endEffector.a.y = 0.0f; endEffector.a.z = 0.0f;  for (int ii = 0; ii < 5; ii++)  {    joints[ii] = 0.0f;    jointOffsets[ii] = 0.0f;    jointMin[ii] = 0.0f;    jointMax[ii] = 0.0f;  }}/////////////////////////////////////////////////////////////////////////////////  Accessor functions///////////////////////////////////////////////////////////////////////////////void KineCalc::SetP (double newPX, double newPY, double newPZ){  endEffector.p.x = newPX;  endEffector.p.y = newPY;  endEffector.p.z = newPZ;}void KineCalc::SetN (double newNX, double newNY, double newNZ){  endEffector.n.x = newNX;  endEffector.n.y = newNY;  endEffector.n.z = newNZ;}void KineCalc::SetO (double newOX, double newOY, double newOZ){  endEffector.o.x = newOX;  endEffector.o.y = newOY;  endEffector.o.z = newOZ;}void KineCalc::SetA (double newAX, double newAY, double newAZ){  endEffector.a.x = newAX;  endEffector.a.y = newAY;  endEffector.a.z = newAZ;}double KineCalc::GetTheta (unsigned int index){  return joints[index];}void KineCalc::SetTheta (unsigned int index, double newVal){  joints[index] = newVal;}void KineCalc::SetLinkLengths (double newLink1, double newLink2, double newLink3, double newLink4, double newLink5){  link1 = newLink1;  link2 = newLink2;  link3 = newLink3;  link4 = newLink4;  link5 = newLink5;}void KineCalc::SetOffset (unsigned int joint, double newOffset){  jointOffsets[joint] = newOffset;}void KineCalc::SetJointRange (unsigned int joint, double min, double max){  jointMin[joint] = MIN (min, max);   // So that if min > max we reverse them  jointMax[joint] = MAX (min, max);}/////////////////////////////////////////////////////////////////////////////////  Utility helper functions///////////////////////////////////////////////////////////////////////////////KineVector KineCalc::Normalise (const KineVector &vector){  KineVector result;  double length = sqrt (vector.x * vector.x + vector.y * vector.y + vector.z * vector.z);  result.x = vector.x / length;  result.y = vector.y / length;  result.z = vector.z / length;  return result;}KineVector KineCalc::CalculateN (const EndEffector &pose){  KineVector result;  result.x = pose.o.y * pose.a.z - pose.a.y * pose.o.z;  result.y = pose.o.z * pose.a.x - pose.a.z * pose.o.x;  result.z = pose.o.x * pose.a.y - pose.a.x * pose.o.y;  return Normalise (result);}void KineCalc::PrintEndEffector (const EndEffector &endEffector){  printf ("P: (%f, %f, %f)\tA: (%f, %f, %f)\tO: (%f, %f, %f)\tN: (%f, %f, %f)\n",          endEffector.p.x, endEffector.p.y, endEffector.p.z,          endEffector.a.x, endEffector.a.y, endEffector.a.z,          endEffector.o.x, endEffector.o.y, endEffector.o.z,          endEffector.n.x, endEffector.n.y, endEffector.n.z);}/////////////////////////////////////////////////////////////////////////////////  The important functions/////////////////////////////////////////////////////////////////////////////////  Calculate the forward kinematics//  The result is stored in endEffector//  fromJoints[]:   An array of 5 joint valuesvoid KineCalc::CalculateFK (const double fromJoints[]){  double adjustedJoints[5];  adjustedJoints[0] = (fromJoints[0] - jointOffsets[0]) * -1;  adjustedJoints[1] = fromJoints[1] - jointOffsets[1];  adjustedJoints[2] = fromJoints[2] - jointOffsets[2];  adjustedJoints[3] = (fromJoints[3] - jointOffsets[3]) * -1;;  adjustedJoints[4] = (fromJoints[4] - jointOffsets[4]) * -1;;  endEffector = CalcFKForJoints (adjustedJoints);//  printf ("Result of FK:\n");//  PrintEndEffector (endEffector);}//  Calculate the inverse kinematics//  The result is stored in joints//  fromPosition:   An EndEffector structure describing the pose//                  of the end effectorbool KineCalc::CalculateIK (const EndEffector &fromPosition){  // Some references to make the code neater  const KineVector &p = fromPosition.p;  const KineVector &a = fromPosition.a;  // These are the four possible solutions to the IK  // solution1 = {1a, 2a, 3a, 4a, 5a}  // solution2 = {1a, 2b, 3b, 4b, 5b}  // solution3 = {1b, 2c, 3c, 4c, 5c}  // solution4 = {1b, 2d, 3d, 4d, 5d}  double solutions[4][5];  double temp = 0.0f;  // First calculate the two possible values for theta1, theta1a and theta1b  temp = atan2 (p.y - link5 * a.y, p.x - link5 * a.x);  solutions[0][0] = solutions[1][0] = temp;  temp = atan2 (link5 * a.y - p.y, link5 * a.x - p.x);  solutions[2][0] = solutions[3][0] = temp;  // Next, using theta1_a, calculate thetas 2 and 3 (a and b)  // First up is calculating r and rz  double r = 0.0f, rz = 0.0f;  if (sin (solutions[0][0]) < 0.1f || sin(solutions[0][0]) > -0.1f)  {    r = ((p.x - (link5 * a.x)) / cos (solutions[0][0])) - link1;  }  else  {    r = ((p.y - (link5 * a.y)) / sin (solutions[0][0])) - link1;  }  rz = p.z - (link5 * a.z);  // Then calculate theta2a and 3a  temp = (r * r + rz * rz + link2 * link2 - link4 * link4) / (2 * link2 * sqrt (r * r + rz * rz));  temp = MIN (MAX (temp, -1.0f), 1.0f);  temp = atan2 (rz, r) - acos (temp);  int m1 = -1;  do  {    if (m1 > 1)    {      printf ("m1 > 1!\n");      break;    }    solutions[0][1] = temp + 2 * m1 * M_PI;    m1 += 1;  // So that within the 3 iterations we get m1 = -1, 0, 1  } // Put a catchall here to prevent infinite loops by checking if m1 has gone past 1 (shouldn't happen)  while ((solutions[0][1] < -(M_PI) || solutions[0][1] > M_PI));// && m1 < 1);  temp = (link2 * link2 + link4 * link4 - r * r - rz * rz) / (2 * link2 * link4);  temp = MIN (MAX (temp, -1.0f), 1.0f);  solutions[0][2] = M_PI - acos (temp);  // Followed by theta2b and 3b  temp = (r * r + rz * rz + link2 * link2 - link4 * link4) / (2 * link2 * sqrt (r * r + rz * rz));  temp = MIN (MAX (temp, -1.0f), 1.0f);  temp = atan2 (rz, r) + acos (temp);  m1 = -1;  do  {    if (m1 > 1)    {      break;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -