Download src/Mod/Robot/App/Robot6Axis.cpp from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 10.5 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Robot/App/Robot6Axis.cpp
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/Robot/App/Robot6Axis.cpp
-
curl -L -o Robot6Axis.cpp https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Robot/App/Robot6Axis.cpp
10.5 kB
| // SPDX-License-Identifier: LGPL-2.1-or-later | |
| /*************************************************************************** | |
| * Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> * | |
| * * | |
| * This file is part of the FreeCAD CAx development system. * | |
| * * | |
| * This library is free software; you can redistribute it and/or * | |
| * modify it under the terms of the GNU Library General Public * | |
| * License as published by the Free Software Foundation; either * | |
| * version 2 of the License, or (at your option) any later version. * | |
| * * | |
| * This library 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 Library General Public License for more details. * | |
| * * | |
| * You should have received a copy of the GNU Library General Public * | |
| * License along with this library; see the file COPYING.LIB. If not, * | |
| * write to the Free Software Foundation, Inc., 59 Temple Place, * | |
| * Suite 330, Boston, MA 02111-1307, USA * | |
| * * | |
| ***************************************************************************/ | |
| namespace Robot | |
| { | |
| // clang-format off | |
| // some default roboter | |
| AxisDefinition KukaIR500[6] = { | |
| // a ,alpha ,d ,theta ,rotDir ,maxAngle ,minAngle ,AxisVelocity | |
| {500 ,-90 ,1045 ,0 , -1 ,+185 ,-185 ,156 }, // Axis 1 | |
| {1300 ,0 ,0 ,0 , 1 ,+35 ,-155 ,156 }, // Axis 2 | |
| {55 ,+90 ,0 ,-90 , 1 ,+154 ,-130 ,156 }, // Axis 3 | |
| {0 ,-90 ,-1025,0 , 1 ,+350 ,-350 ,330 }, // Axis 4 | |
| {0 ,+90 ,0 ,0 , 1 ,+130 ,-130 ,330 }, // Axis 5 | |
| {0 ,+180 ,-300 ,0 , 1 ,+350 ,-350 ,615 } // Axis 6 | |
| }; | |
| // clang-format on | |
| TYPESYSTEM_SOURCE(Robot::Robot6Axis, Base::Persistence) | |
| Robot6Axis::Robot6Axis() | |
| : Actual(KDL::JntArray(6)) | |
| , Min(KDL::JntArray(6)) | |
| , Max(KDL::JntArray(6)) | |
| { | |
| // set to default kuka 500 | |
| setKinematic(KukaIR500); | |
| } | |
| void Robot6Axis::setKinematic(const AxisDefinition KinDef[6]) | |
| { | |
| KDL::Chain temp; | |
| for (int i = 0; i < 6; i++) { | |
| temp.addSegment( | |
| KDL::Segment( | |
| KDL::Joint(KDL::Joint::RotZ), | |
| KDL::Frame::DH( | |
| KinDef[i].a, | |
| Base::toRadians<double>(KinDef[i].alpha), | |
| KinDef[i].d, | |
| Base::toRadians<double>(KinDef[i].theta) | |
| ) | |
| ) | |
| ); | |
| RotDir[i] = KinDef[i].rotDir; | |
| Max(i) = Base::toRadians<double>(KinDef[i].maxAngle); | |
| Min(i) = Base::toRadians<double>(KinDef[i].minAngle); | |
| Velocity[i] = KinDef[i].velocity; | |
| } | |
| // for now and testing | |
| Kinematic = temp; | |
| // get the actual TCP out of the axis | |
| calcTcp(); | |
| } | |
| double Robot6Axis::getMaxAngle(int Axis) | |
| { | |
| return Base::toDegrees<double>(Max(Axis)); | |
| } | |
| double Robot6Axis::getMinAngle(int Axis) | |
| { | |
| return Base::toDegrees<double>(Min(Axis)); | |
| } | |
| void split(std::string const& string, const char delimiter, std::vector<std::string>& destination) | |
| { | |
| std::string::size_type last_position(0); | |
| std::string::size_type position(0); | |
| for (std::string::const_iterator it(string.begin()); it != string.end(); ++it, ++position) { | |
| if (*it == delimiter) { | |
| destination.push_back(string.substr(last_position, position - last_position)); | |
| last_position = position + 1; | |
| } | |
| } | |
| destination.push_back(string.substr(last_position, position - last_position)); | |
| } | |
| void Robot6Axis::readKinematic(const char* FileName) | |
| { | |
| char buf[120]; | |
| Base::FileInfo fi(FileName); | |
| Base::ifstream in(fi); | |
| if (!in) { | |
| return; | |
| } | |
| std::vector<std::string> destination; | |
| AxisDefinition temp[6]; | |
| // over read the header | |
| in.getline(buf, 119, '\n'); | |
| // read 6 Axis | |
| for (auto& i : temp) { | |
| in.getline(buf, 79, '\n'); | |
| destination.clear(); | |
| split(std::string(buf), ',', destination); | |
| if (destination.size() < 8) { | |
| continue; | |
| } | |
| // transfer the values in kinematic structure | |
| i.a = atof(destination[0].c_str()); | |
| i.alpha = atof(destination[1].c_str()); | |
| i.d = atof(destination[2].c_str()); | |
| i.theta = atof(destination[3].c_str()); | |
| i.rotDir = atof(destination[4].c_str()); | |
| i.maxAngle = atof(destination[5].c_str()); | |
| i.minAngle = atof(destination[6].c_str()); | |
| i.velocity = atof(destination[7].c_str()); | |
| } | |
| setKinematic(temp); | |
| } | |
| unsigned int Robot6Axis::getMemSize() const | |
| { | |
| return 0; | |
| } | |
| void Robot6Axis::Save(Base::Writer& writer) const | |
| { | |
| for (unsigned int i = 0; i < 6; i++) { | |
| Base::Placement Tip = toPlacement(Kinematic.getSegment(i).getFrameToTip()); | |
| writer.Stream() << writer.ind() << "<Axis " | |
| << "Px=\"" << Tip.getPosition().x << "\" " | |
| << "Py=\"" << Tip.getPosition().y << "\" " | |
| << "Pz=\"" << Tip.getPosition().z << "\" " | |
| << "Q0=\"" << Tip.getRotation()[0] << "\" " | |
| << "Q1=\"" << Tip.getRotation()[1] << "\" " | |
| << "Q2=\"" << Tip.getRotation()[2] << "\" " | |
| << "Q3=\"" << Tip.getRotation()[3] << "\" " | |
| << "rotDir=\"" << RotDir[i] << "\" " | |
| << "maxAngle=\"" << Base::toDegrees<double>(Max(i)) << "\" " | |
| << "minAngle=\"" << Base::toDegrees<double>(Min(i)) << "\" " | |
| << "AxisVelocity=\"" << Velocity[i] << "\" " | |
| << "Pos=\"" << Actual(i) << "\"/>" << std::endl; | |
| } | |
| } | |
| void Robot6Axis::Restore(Base::XMLReader& reader) | |
| { | |
| KDL::Chain Temp; | |
| Base::Placement Tip; | |
| for (unsigned int i = 0; i < 6; i++) { | |
| // read my Element | |
| reader.readElement("Axis"); | |
| // get the value of the placement | |
| Tip = Base::Placement( | |
| Base::Vector3d( | |
| reader.getAttribute<double>("Px"), | |
| reader.getAttribute<double>("Py"), | |
| reader.getAttribute<double>("Pz") | |
| ), | |
| Base::Rotation( | |
| reader.getAttribute<double>("Q0"), | |
| reader.getAttribute<double>("Q1"), | |
| reader.getAttribute<double>("Q2"), | |
| reader.getAttribute<double>("Q3") | |
| ) | |
| ); | |
| Temp.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotZ), toFrame(Tip))); | |
| if (reader.hasAttribute("rotDir")) { | |
| Velocity[i] = reader.getAttribute<double>("rotDir"); | |
| } | |
| else { | |
| Velocity[i] = 1.0; | |
| } | |
| // read the axis constraints | |
| Min(i) = Base::toRadians<double>(reader.getAttribute<double>("maxAngle")); | |
| Max(i) = Base::toRadians<double>(reader.getAttribute<double>("minAngle")); | |
| if (reader.hasAttribute("AxisVelocity")) { | |
| Velocity[i] = reader.getAttribute<double>("AxisVelocity"); | |
| } | |
| else { | |
| Velocity[i] = 156.0; | |
| } | |
| Actual(i) = reader.getAttribute<double>("Pos"); | |
| } | |
| Kinematic = Temp; | |
| calcTcp(); | |
| } | |
| bool Robot6Axis::setTo(const Base::Placement& To) | |
| { | |
| // Creation of the solvers: | |
| KDL::ChainFkSolverPos_recursive fksolver1(Kinematic); // Forward position solver | |
| KDL::ChainIkSolverVel_pinv iksolver1v(Kinematic); // Inverse velocity solver | |
| KDL::ChainIkSolverPos_NR_JL iksolver1( | |
| Kinematic, | |
| Min, | |
| Max, | |
| fksolver1, | |
| iksolver1v, | |
| 100, | |
| 1e-6 | |
| ); // Maximum 100 iterations, stop at accuracy 1e-6 | |
| // Creation of jntarrays: | |
| KDL::JntArray result(Kinematic.getNrOfJoints()); | |
| // Set destination frame | |
| KDL::Frame F_dest = KDL::Frame( | |
| KDL::Rotation::Quaternion( | |
| To.getRotation()[0], | |
| To.getRotation()[1], | |
| To.getRotation()[2], | |
| To.getRotation()[3] | |
| ), | |
| KDL::Vector(To.getPosition()[0], To.getPosition()[1], To.getPosition()[2]) | |
| ); | |
| // solve | |
| if (iksolver1.CartToJnt(Actual, F_dest, result) < 0) { | |
| return false; | |
| } | |
| else { | |
| Actual = result; | |
| Tcp = F_dest; | |
| return true; | |
| } | |
| } | |
| Base::Placement Robot6Axis::getTcp() | |
| { | |
| double x, y, z, w; | |
| Tcp.M.GetQuaternion(x, y, z, w); | |
| return Base::Placement(Base::Vector3d(Tcp.p[0], Tcp.p[1], Tcp.p[2]), Base::Rotation(x, y, z, w)); | |
| } | |
| bool Robot6Axis::calcTcp() | |
| { | |
| // Create solver based on kinematic chain | |
| KDL::ChainFkSolverPos_recursive fksolver = KDL::ChainFkSolverPos_recursive(Kinematic); | |
| // Create the frame that will contain the results | |
| KDL::Frame cartpos; | |
| // Calculate forward position kinematics | |
| int kinematics_status; | |
| kinematics_status = fksolver.JntToCart(Actual, cartpos); | |
| if (kinematics_status >= 0) { | |
| Tcp = cartpos; | |
| return true; | |
| } | |
| else { | |
| return false; | |
| } | |
| } | |
| bool Robot6Axis::setAxis(int Axis, double Value) | |
| { | |
| Actual(Axis) = RotDir[Axis] * Base::toRadians<double>(Value); | |
| return calcTcp(); | |
| } | |
| double Robot6Axis::getAxis(int Axis) | |
| { | |
| return RotDir[Axis] * Base::toDegrees<double>(Actual(Axis)); | |
| } | |
| } /* namespace Robot */ | |