From 60ea6f36bd9fb4215b1ba937ec749f356e582ac1 Mon Sep 17 00:00:00 2001 From: ros Date: Mon, 19 May 2025 18:18:05 +0200 Subject: [PATCH] Added full servoeing. --- bin/CameraOrientationTracking | Bin 157864 -> 157864 bytes bin/RedBallDetection | Bin 44048 -> 44048 bytes bin/RedBallTracking | Bin 40192 -> 40192 bytes bin/RobotServoing | Bin 0 -> 139304 bytes data/camera_chessboard_calibration_params.xml | 66 +-- data/color_params.xml | 8 +- data/color_params_data.xml | 9 + data/color_params_data2.xml | 9 + include/DynamixelHandler.h | 88 ++++ include/Kinematics.h | 20 + lib/CameraOrientationTracking.o | Bin 246424 -> 246424 bytes lib/DynamixelHandler.o | Bin 0 -> 87200 bytes lib/Kinematics.o | Bin 0 -> 192440 bytes lib/RedBallDetection.o | Bin 40456 -> 40464 bytes lib/RobotServoing.o | Bin 0 -> 191672 bytes makefile | 24 +- src/CameraOrientationTracking.cpp | 4 +- src/DynamixelHandler.cpp | 407 ++++++++++++++++++ src/Kinematics.cpp | 161 +++++++ src/RedBallDetection.cpp | 33 +- src/RobotServoing.cpp | 321 ++++++++++++++ 21 files changed, 1088 insertions(+), 62 deletions(-) create mode 100755 bin/RobotServoing create mode 100644 data/color_params_data.xml create mode 100644 data/color_params_data2.xml create mode 100644 include/DynamixelHandler.h create mode 100644 include/Kinematics.h create mode 100644 lib/DynamixelHandler.o create mode 100644 lib/Kinematics.o create mode 100644 lib/RobotServoing.o create mode 100644 src/DynamixelHandler.cpp create mode 100644 src/Kinematics.cpp create mode 100644 src/RobotServoing.cpp diff --git a/bin/CameraOrientationTracking b/bin/CameraOrientationTracking index d29f1419167461df2367274dda2b922ec1d1c331..3f610c49a54f658d05e6bf34b9922b3457fdcc0e 100755 GIT binary patch delta 916 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 diff --git a/bin/RedBallTracking b/bin/RedBallTracking index 5e08137a361b07094f7e69b543abf8257e01706e..1a2830012cdb2b066ff86830069318cf4aa6c026 100755 GIT binary patch delta 545 zcmY*UODIH97(Qoa?wE&pq3#`#*cgv=jSWRH24gX^_F4=h&B9936p6AJLl~chWG5C# zQzXqo2-&c*kcA>yDK<*kIQPF};VjPiUg!JInaLVvvW86DSfm~-*2R+V_Sxb2%aOfc zYL`tXFlF529~d;r9NLbMN#WO+m1HDLD)-=AI19udgma~FSR|F-qh2_@bTbN%S>{Ki z_^2f#5)F8kWIjpiILa+Dd}f7zQ8q=rFVve9>OP?pbCgF2sd*|N&~74;r|KUS)(d4)##GeS=SQMVsrr}$lAL{j4Rl~7_KI@X-YhbK`x!GwaqZQN- z)-LIKrb`#@a{4wyv8_|-$=O5Qy1tRK!CeX>E2Rk8s}WePK#Qx=?vG70ga^li{*DPm zUB`&0Yp~|bKd+V!i$~woUuVaT<^TWy delta 550 zcmZqJ#niBiX+s9H$eP0wxBS{-^1htcdEqmMp6*-xj~XY}FwbF(nEa7NoH2cJBdhpi z4;BeV;mL+9;*%>_3>e)e3$lq%KEN(9`36v23ao;I)qs%`B+jS{;xkSFsb+jRIT1*1 z0;}HuRB>+dL!jJ#u;`x2jzCj1*d!Q@KrBWfFsTo=r2{DX6J-D79c&4VX(08J4cHAB z7l2t6>=KN3!6q?+^}GVxwFx9L`2$eZbg+F5vsfm#u!=CsgU!j{@L+TYvrceGFlvL% z`2l2kfbG-ZG+_G2JUNQ9&u9Z91A`KS0K+~v1~71ePz>G75b+J}5P@@0aSO)DQe18l z3!u_To)Ga_Q0d9rc@!tR@CZ%5&eJe?0+;*bl!*>Jen!b<#=eOqE=I0plS6s4_~N7B zLWV%0mwY!S-{Xy%tT91iavqP!WF8*L$wJ);laKN@Og_XbGueXAdh!`Q4esRpqEx-& zd_5CAqseytYLkC*sZUnr5uEJ6y>PN7kJRL4JffRj1r|pe?FV`a1fUc{ITI>hhy|73 L#j;r{=a~Tjak7x+ diff --git a/bin/RobotServoing b/bin/RobotServoing new file mode 100755 index 0000000000000000000000000000000000000000..e485a3c046e42b889b884ac0b8a93d06548ee213 GIT binary patch literal 139304 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%0AcSvKN~JN(wHUE{(*Pm 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 - 5.88612000e+02 2.15689667e+02 5.54606873e+02 2.15611755e+02 - 5.20468445e+02 2.15258972e+02 4.85772522e+02 2.15278687e+02 - 4.51321503e+02 2.15120773e+02 4.16495636e+02 2.14783768e+02 - 3.81401917e+02 2.14718674e+02 3.46348175e+02 2.14802200e+02 - 3.10953491e+02 2.15044067e+02 5.88692505e+02 1.81895676e+02 - 5.54564270e+02 1.81450623e+02 5.20432983e+02 1.80957260e+02 - 4.85783722e+02 1.80860062e+02 4.51179932e+02 1.80639709e+02 - 4.16396912e+02 1.80453308e+02 3.81144226e+02 1.80382690e+02 - 3.45956238e+02 1.80322159e+02 3.10507690e+02 1.80347870e+02 - 5.88607361e+02 1.48160278e+02 5.54770813e+02 1.47601761e+02 - 5.20398499e+02 1.47191406e+02 4.85810608e+02 1.46545593e+02 - 4.50779694e+02 1.46543564e+02 4.15969879e+02 1.46196732e+02 - 3.80619965e+02 1.45882202e+02 3.45383270e+02 1.45875610e+02 - 3.09773987e+02 1.46258408e+02 5.89240051e+02 1.14398933e+02 - 5.54773438e+02 1.13560555e+02 5.20508728e+02 1.13239220e+02 - 4.85565887e+02 1.12632996e+02 4.50695831e+02 1.12478821e+02 - 4.15567413e+02 1.12141571e+02 3.80236389e+02 1.11906654e+02 - 3.44660980e+02 1.11700226e+02 3.09211731e+02 1.11827919e+02 - 5.89326904e+02 8.11330795e+01 5.55244568e+02 8.04520645e+01 - 5.20487244e+02 7.96654358e+01 4.85463074e+02 7.93521194e+01 - 4.50391876e+02 7.91115799e+01 4.15237152e+02 7.86507416e+01 - 3.79536346e+02 7.84776230e+01 3.43838593e+02 7.84099808e+01 - 3.08281067e+02 7.82369461e+01 5.89964478e+02 4.79190063e+01 - 5.55360474e+02 4.72442245e+01 5.20573486e+02 4.66231613e+01 - 4.85435333e+02 4.63138351e+01 4.50215057e+02 4.57072220e+01 - 4.14667877e+02 4.53788414e+01 3.78956207e+02 4.50921440e+01 - 3.43222778e+02 4.47188683e+01 3.07135529e+02 4.45427628e+01 + 2.45399948e+02 3.96526428e+02 2.75491119e+02 3.96743744e+02 + 3.05529846e+02 3.97404755e+02 3.35598389e+02 3.97747894e+02 + 3.65435516e+02 3.98247070e+02 3.95277130e+02 3.98678436e+02 + 4.24790131e+02 3.99188873e+02 4.54343109e+02 3.99793427e+02 + 4.83617188e+02 4.00341827e+02 2.43551071e+02 4.26507141e+02 + 2.73815063e+02 4.26920990e+02 3.04072540e+02 4.27350433e+02 + 3.34468323e+02 4.27689362e+02 3.64420837e+02 4.28136353e+02 + 3.94441345e+02 4.28616119e+02 4.24255005e+02 4.28880920e+02 + 4.53849121e+02 4.29541565e+02 4.83251129e+02 4.30148285e+02 + 2.41581970e+02 4.56861023e+02 2.72229858e+02 4.57136444e+02 + 3.02617950e+02 4.57337982e+02 3.33223389e+02 4.57670135e+02 + 3.63343964e+02 4.58243011e+02 3.93526886e+02 4.58544525e+02 + 4.23598541e+02 4.59073547e+02 4.53499939e+02 4.59387024e+02 + 4.83260071e+02 4.59713501e+02 2.39441559e+02 4.87543976e+02 + 2.70317017e+02 4.87674408e+02 3.00955750e+02 4.87926483e+02 + 3.31665344e+02 4.88370178e+02 3.62285126e+02 4.88526459e+02 + 3.92531311e+02 4.88930115e+02 4.22826599e+02 4.89222931e+02 + 4.52897003e+02 4.89462860e+02 4.82814758e+02 4.89736603e+02 + 2.36905212e+02 5.18513794e+02 2.68179993e+02 5.18365417e+02 + 2.99221039e+02 5.18484436e+02 3.30290558e+02 5.18595032e+02 + 3.61055054e+02 5.18633667e+02 3.91492371e+02 5.19132996e+02 + 4.22201019e+02 5.19357239e+02 4.52542633e+02 5.19609009e+02 + 4.82629883e+02 5.19963745e+02 2.33913452e+02 5.49964966e+02 + 2.65571899e+02 5.49619385e+02 2.97115417e+02 5.49631531e+02 + 3.28535370e+02 5.49592285e+02 3.59526276e+02 5.49615601e+02 + 3.90559509e+02 5.49705688e+02 4.21580505e+02 5.49908875e+02 + 4.52188660e+02 5.50283813e+02 4.82645752e+02 5.50572266e+02 4 4

d
- -9.9999815881189502e-01 1.2697535215647785e-03 - 1.4387837969518850e-03 1.2288328754052873e+02 - -1.2718960354282296e-03 -9.9999808231089615e-01 - -1.4891793059053041e-03 -2.7774165634818203e+01 - 1.4368901471439603e-03 -1.4910065474532613e-03 - 9.9999785612079128e-01 5.2883271790406673e+02 0. 0. 0. 1. + 9.9988271709700483e-01 -8.6495461050344179e-03 + -1.2638726315885510e-02 -1.2258087320730928e+02 + 1.2737430271251139e-02 9.2786987434153378e-01 3.7268653605880536e-01 + 1.0601197521882341e+02 8.5035240221915127e-03 + -3.7280381119511524e-01 9.2787122405946010e-01 + 6.1627442399943686e+02 0. 0. 0. 1. diff --git a/data/color_params.xml b/data/color_params.xml index fcedfef..31598ee 100644 --- a/data/color_params.xml +++ b/data/color_params.xml @@ -1,9 +1,9 @@ -0 -179 -105 +14 +19 +119 255 -210 +0 255 diff --git a/data/color_params_data.xml b/data/color_params_data.xml new file mode 100644 index 0000000..31598ee --- /dev/null +++ b/data/color_params_data.xml @@ -0,0 +1,9 @@ + + +14 +19 +119 +255 +0 +255 + diff --git a/data/color_params_data2.xml b/data/color_params_data2.xml new file mode 100644 index 0000000..fcedfef --- /dev/null +++ b/data/color_params_data2.xml @@ -0,0 +1,9 @@ + + +0 +179 +105 +255 +210 +255 + diff --git a/include/DynamixelHandler.h b/include/DynamixelHandler.h new file mode 100644 index 0000000..da1a9a6 --- /dev/null +++ b/include/DynamixelHandler.h @@ -0,0 +1,88 @@ +#if defined(__linux__) || defined(__APPLE__) +#include +#include +#include +#define STDIN_FILENO 0 +#elif defined(_WIN32) || defined(_WIN64) +#include +#endif + +#define _USE_MATH_DEFINES +#include + +// standard includes +#include +#include +#include +#include +#include + +// dynamixel sdk include +#include "dynamixel_sdk/dynamixel_sdk.h" + +// addresses of variables in the register +#define ADDR_XL320_CONTROL_MODE 11 +#define ADDR_XL320_TORQUE_ENABLE 24 +#define ADDR_XL320_GOAL_POSITION 30 +#define ADDR_XL320_GOAL_VELOCITY 32 +#define ADDR_XL320_PRESENT_POSITION 37 +#define ADDR_XL320_PRESENT_VELOCITY 39 +#define ADDR_XL320_HARDWARE_ERROR_STATUS 50 + +// rotation direction +#define ROT_DIRECTION_Q1 1 +#define ROT_DIRECTION_Q2 -1 +#define ROT_DIRECTION_QPEN 1 +// nb of joints +#define NB_JOINTS 3 + + +class DynamixelHandler +{ + +public: + DynamixelHandler(); + ~DynamixelHandler(); + +public: + bool openPort(); + void closePort(); + bool setBaudRate(int); + void setDeviceName(std::string); + void setProtocolVersion(float); + bool enableTorque(bool); + bool setControlMode(int iControlMode); + + bool readCurrentJointPosition(std::vector& vCurrentJointPosition); + bool readCurrentJointPosition(std::vector& vCurrentJointPosition); + bool sendTargetJointPosition(std::vector& vTargetJointPosition); + bool sendTargetJointPosition(std::vector& vTargetJointPosition); + bool sendTargetJointVelocity(std::vector& vTargetJointVelocity); + bool sendTargetJointVelocity(std::vector& vTargetJointVelocity); + int convertAngleToJointCmd(float fJointAngle); + float convertJointCmdToAngle(int iJointCmd); + int convertJointVelocityToJointCmd(float fJointVelocity); + +private: + std::string m_sDeviceName; + float m_fProtocolVersion; + int m_i32BaudRate; + + dynamixel::PortHandler* m_pPortHandler; + dynamixel::PacketHandler* m_pPacketHandler; + + bool m_bIsDeviceNameSet; + bool m_bIsProtocolVersionSet; + bool m_bIsPortOpened; + bool m_bIsBaudRateSet; + + int m_i32DxlCommunicationResult; // Communication result + uint8_t m_ui8DxlError; // Dynamixel error + std::vector m_vDxlCurrentPosition; // Present position + + float m_fMinJointCmd = 0; + float m_fMaxJointCmd = 1023; + float m_fMinJointAngle = -150.0f/180.0f*M_PI; + float m_fMaxJointAngle = 150.0f/180.0f*M_PI; + +}; \ No newline at end of file diff --git a/include/Kinematics.h b/include/Kinematics.h new file mode 100644 index 0000000..04fc5e1 --- /dev/null +++ b/include/Kinematics.h @@ -0,0 +1,20 @@ +#define _USE_MATH_DEFINES +#include +#include +#include + +#include "opencv2/opencv.hpp" + +float deg2rad(float angle); + +float rad2deg(float angle); + +std::vector computeForwardKinematics(float q1, float q2, float L1, float L2); + +std::vector computeInverseKinematics(float x, float y, float L1, float L2); + +std::vector computeDifferentialKinematics(float q1, float q2, float L1, float L2); + +int computeJacobianMatrixRank(std::vector vJacobianMatrix, float threshold); + +cv::Mat computeInverseJacobianMatrix(std::vector vJacobianMatrix); diff --git a/lib/CameraOrientationTracking.o b/lib/CameraOrientationTracking.o index 69556e81f69cc83b1d6d4e7cc3f5727186457ed5..a6feb4733b727bbba73bb399c782963741fabdb2 100644 GIT binary patch delta 29 jcmbQy%0Hu(e*>Q}(+9_90poT7V@4om+Ad(s+|dsJkmCsM delta 29 jcmbQy%0Hu(e*>Q}(*lQP0poT7V@4om+Ad(s+|dsJis1;I diff --git a/lib/DynamixelHandler.o b/lib/DynamixelHandler.o new file mode 100644 index 0000000000000000000000000000000000000000..eb89afce530fb8127c11a36c4fdcae0aa28ab251 GIT binary patch literal 87200 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 literal 0 HcmV?d00001 diff --git a/lib/Kinematics.o b/lib/Kinematics.o new file mode 100644 index 0000000000000000000000000000000000000000..921b0f63a4a5ff7c127110eecd6ac523701ad2d1 GIT binary patch literal 192440 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 H&E)?d@o(dc literal 0 HcmV?d00001 diff --git a/lib/RedBallDetection.o b/lib/RedBallDetection.o index 7ebbe51e2cdd473d1372b6edc636b2d56d04ff0f..1fdfd1d73160f87b7b8b788d4857778a2b6d2eb4 100644 GIT binary patch delta 862 zcmX}pPe>F|90&0Et!w@%Xq9j^h#J{&C0HrKY7b3b+)X?b%I3jZpRT$qE32zy#p2o_ zvXidg(*9Xa6yeEa2r>+$*!jHge0lTU%+BbdZJd8@ za?Dp>D<%VT#ZTD%yBqLu=g|MuVl3>M$fp^jv6M>p`IT^_JM34Yv7sg_Hpv*UVgNm^ zLvBw^NDPXaj#xAn5B7<;=pFD}>WwPih_}ld^A339UPT^w?t0J5`K{#|<#IAMDI5b< z3>Z%jrVdlcIB_nPzc-p^-KBia-yUr|$Vh}YtsYv%_f{vZ8b#;li1uLN!Wh-!bTCNG zm<=vb0+F_LT11@~qmM{iigq7;!fg8zH<1n>Wij6&bAQN3->?vp`EsX^e&BVd%vZa7 z^b0FpGT-R-(QhN&T|hRw&G-=hSwKgT?pvaIr25Bb5Nf=Jw>}#mqU%_RuhU~gANW&f zv*+Pa!b2{k6HW>kUlLVBYbY6ZR=krh#D^T@xm+Nx6eWYYVJAk19YwEpY&RR|=jH`B zYq>dD=-gzv$>f?%q`4_iI*O)pcWr@^PWY3K%4}|qlKV&h?O2iP?RiE+vaEz!AjaR) z2&z-Zs2n1tksCVO43iB*ozUn31Umwq&A?=zL50R&K(H?8>;_D>73xim91v^*I_rkX z9)WsGlY6ljp|e+DvZGKZ5GtomQYFNcMj_~I8BDew>TQjBAlM1$ z>`Rzz8`L`*e;vUtLuW@|vKgp%HTnv{ZbD~^VX~*7-qWZMg7rgZ55Q#4K)o*?U9kMZ U>>cMTrVg*abV$D;r2gmj@MoZKZWU#fa-xI5=tKbIW$04XL zx<2JcyV5Cey2v&i5)2W9EIcR~y5vDbqM;57Asv?NKjU25h55bDzR$}$@5_wN3s2^S z(F)2*ijQ;Y5VN_jaqjdDygJ!ujrH1G-dGmZYTiOBJnOTyD{bvQTPWNon^88R$BZ64 zEW7Az3WvgxKvysl?C1&jWREM_5wf`zcdI+>?r}%l_)zwhx2ZF?@fzD0QMPgPn9-xn zo{v?NU%PfUoJGw@`t8DB8$SD8jwQin{*>cKqwzP3pCzr}{wz@*79Wg|3%3IS@*){n zpk8!0Y|uMg5020mq)e4YnZ6;}xWF^rO)_m`uF1%cnq~Tq#bzT9x5)GppIVIkv{j~k zthE|B)+W<|mTJo;Ax+v&`$0BcLaJ+lYB1G3LLrEeDt`67NFNPiEwVugP3<|%5z+$Q z^t&7-$Bxe3S^EF^Z)*Gf<>Xklu4fF!6SJP2)%0Aj;9YJn4Gujoa-9n7p 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 literal 0 HcmV?d00001 diff --git a/makefile b/makefile index 2e0036e..53d177c 100644 --- a/makefile +++ b/makefile @@ -1,23 +1,33 @@ -all: ReadWrite MonoCamCalib RedBallDetection RedBallTracking CameraOrientationTracking +all: ReadWrite MonoCamCalib RedBallDetection RedBallTracking CameraOrientationTracking Kinematics Dxl Servoing g++ lib/MonoCameraCalibration.o lib/ReadWriteFunctions.o -o bin/MonoCameraCalibration -L/usr/lib/x86_64-linux-gnu `pkg-config --libs opencv4` - g++ lib/RedBallDetection.o -o bin/RedBallDetection -L/usr/lib/x86_64-linux-gnu `pkg-config --libs opencv4` - g++ lib/RedBallTracking.o -o bin/RedBallTracking -L/usr/lib/x86_64-linux-gnu `pkg-config --libs opencv4` - g++ lib/CameraOrientationTracking.o lib/ReadWriteFunctions.o -o bin/CameraOrientationTracking -L/usr/lib/x86_64-linux-gnu `pkg-config --libs opencv4` + g++ lib/RedBallDetection.o -o bin/RedBallDetection -L/usr/lib/x86_64-linux-gnu -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_aruco -lopencv_videoio -lopencv_objdetect -lopencv_imgcodecs -lopencv_features2d -lopencv_calib3d + g++ lib/RedBallTracking.o -o bin/RedBallTracking -L/usr/lib/x86_64-linux-gnu -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_aruco -lopencv_videoio -lopencv_objdetect -lopencv_imgcodecs -lopencv_features2d -lopencv_calib3d + g++ lib/CameraOrientationTracking.o lib/ReadWriteFunctions.o -o bin/CameraOrientationTracking -L/usr/lib/x86_64-linux-gnu -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_aruco -lopencv_videoio -lopencv_objdetect -lopencv_imgcodecs -lopencv_features2d -lopencv_calib3d + g++ -o bin/RobotServoing lib/RobotServoing.o lib/Kinematics.o lib/DynamixelHandler.o -L/usr/local/lib/ -ldxl_x64_cpp -lrt -L/usr/lib/x86_64-linux-gnu `pkg-config --libs opencv4` MonoCamCalib: src/MonoCameraCalibration.cpp g++ -c src/MonoCameraCalibration.cpp -o lib/MonoCameraCalibration.o -I./include -I/usr/include/opencv4 - + ReadWrite: src/ReadWriteFunctions.cpp g++ -c src/ReadWriteFunctions.cpp -o lib/ReadWriteFunctions.o -I./include -I/usr/include/opencv4 - + RedBallDetection: src/RedBallDetection.cpp g++ -c src/RedBallDetection.cpp -o lib/RedBallDetection.o -I./include -I/usr/include/opencv4 - + RedBallTracking: src/RedBallTracking.cpp g++ -c src/RedBallTracking.cpp -o lib/RedBallTracking.o -I./include -I/usr/include/opencv4 CameraOrientationTracking: src/CameraOrientationTracking.cpp g++ -c src/CameraOrientationTracking.cpp -o lib/CameraOrientationTracking.o -I./include -I/usr/include/opencv4 + +Kinematics: src/Kinematics.cpp + g++ -c src/Kinematics.cpp -o lib/Kinematics.o -I./include -I/usr/include/opencv4 + +Dxl: src/DynamixelHandler.cpp + g++ -c src/DynamixelHandler.cpp -o lib/DynamixelHandler.o -I./include -I/usr/local/include + +Servoing: src/RobotServoing.cpp + g++ -c src/RobotServoing.cpp -o lib/RobotServoing.o -I./include -I/usr/include/opencv4 clean: rm lib/*.o diff --git a/src/CameraOrientationTracking.cpp b/src/CameraOrientationTracking.cpp index fb2f0ee..275e261 100644 --- a/src/CameraOrientationTracking.cpp +++ b/src/CameraOrientationTracking.cpp @@ -12,7 +12,7 @@ #define CAM_PARAMS_FILENAME "./data/camera_calibration_params.xml" #define CAM_CHESSBOARD_CALIB_PARAMS_FILENAME "./data/camera_chessboard_calibration_params.xml" -#define FPS 5.0 +#define FPS 30.0 #define BOARDSIZE_WIDTH 9 #define BOARDSIZE_HEIGHT 6 #define WIN_SIZE 11 @@ -229,4 +229,4 @@ int main( int argc, char** argv ) } return 0; -} \ No newline at end of file +} diff --git a/src/DynamixelHandler.cpp b/src/DynamixelHandler.cpp new file mode 100644 index 0000000..a97b5fd --- /dev/null +++ b/src/DynamixelHandler.cpp @@ -0,0 +1,407 @@ +#include "DynamixelHandler.h" + +DynamixelHandler::DynamixelHandler(): + m_sDeviceName(""), m_fProtocolVersion(0.0), m_i32BaudRate(0), + m_pPacketHandler(nullptr), m_pPortHandler(nullptr), + m_bIsDeviceNameSet(false), m_bIsProtocolVersionSet(false), m_bIsPortOpened(false), m_bIsBaudRateSet(false), + m_ui8DxlError(0), m_i32DxlCommunicationResult(COMM_TX_FAIL) +{ + +} + +DynamixelHandler::~DynamixelHandler() +{ + +} + +int DynamixelHandler::convertJointVelocityToJointCmd(float fJointVelocity) +{ + if (fJointVelocity == 0.0f) + return 0; + + float a = 0.0f; + float b = 0.0f; + if (fJointVelocity>0) + { + float l_fMaxJointCmd = 1023; + float l_fMinJointCmd = 0; + float l_fMaxJointVelocity = 114 * 60.0f * 2 * M_PI; + float l_fMinJointAngle = 0.0f; + // y = ax + b + a = (l_fMaxJointCmd-l_fMinJointCmd) / (l_fMaxJointVelocity - l_fMinJointAngle); + b = l_fMinJointCmd - a * l_fMinJointAngle; + } + + if (fJointVelocity<0) + { + float l_fMaxJointCmd = 2047; + float l_fMinJointCmd = 1024; + float l_fMaxJointVelocity = 0.0f; + float l_fMinJointAngle = -114 * 60.0f * 2 * M_PI; + // y = ax + b + a = (l_fMaxJointCmd-l_fMinJointCmd) / (l_fMaxJointVelocity - l_fMinJointAngle); + b = l_fMinJointCmd - a * l_fMinJointAngle; + } + + float jointCmd = a * fJointVelocity + b; + return (int)jointCmd; +} + +int DynamixelHandler::convertAngleToJointCmd(float fJointAngle) +{ + // y = ax + b + float a = (m_fMaxJointCmd-m_fMinJointCmd) / (m_fMaxJointAngle - m_fMinJointAngle); + float b = m_fMinJointCmd - a * m_fMinJointAngle; + float jointCmd = a * fJointAngle + b; + return (int)jointCmd; +} + +float DynamixelHandler::convertJointCmdToAngle(int iJointCmd) +{ + // y = ax + b + float a = (m_fMaxJointAngle - m_fMinJointAngle) / (m_fMaxJointCmd-m_fMinJointCmd); + float b = m_fMinJointAngle - a * m_fMinJointCmd; + float jointAngle = a * iJointCmd + b; + return jointAngle; +} + +bool DynamixelHandler::openPort() +{ + if (m_pPortHandler == nullptr) + { + std::cout << "[ERROR](DynamixelHandler::openPort) m_pPortHandler is null!" << std::endl; + m_bIsPortOpened = false; + return m_bIsPortOpened; + } + + if (!m_bIsDeviceNameSet) + { + std::cout << "[ERROR](DynamixelHandler::openPort) m_sDeviceName is not set!" << std::endl; + m_bIsPortOpened = false; + return m_bIsPortOpened; + } + + if (m_bIsPortOpened) + { + std::cout << "[WARNING](DynamixelHandler::openPort) port is already opened!" << std::endl; + return m_bIsPortOpened; + } + + if (m_pPortHandler->openPort()) + { + std::cout << "[INFO](DynamixelHandler::openPort) Succeeded to open the port!" << std::endl; + m_bIsPortOpened = true; + } + else + { + std::cout << "[ERROR](DynamixelHandler::openPort) Failed to open the port!" << std::endl; + m_bIsPortOpened = false; + } + return m_bIsPortOpened; +} + +void DynamixelHandler::closePort() +{ + if (m_pPortHandler == nullptr) + { + std::cout << "[ERROR](DynamixelHandler::closePort) m_pPortHandler is null!" << std::endl; + m_bIsPortOpened = false; + return; + } + + if (!m_bIsPortOpened) + { + std::cout << "[WARNING](DynamixelHandler::openPort) port is already closed!" << std::endl; + return; + } + + m_pPortHandler->closePort(); + + std::cout << "[INFO](DynamixelHandler::closePort) Succeeded to close the port!" << std::endl; + m_bIsPortOpened = false; +} + +bool DynamixelHandler::setBaudRate(int i32BaudRate) +{ + m_i32BaudRate = i32BaudRate; + + if (nullptr != m_pPortHandler) + { + if (m_pPortHandler->setBaudRate(m_i32BaudRate)) + { + std::cout << "[INFO](DynamixelHandler::setBaudRate) Succeeded to change the baudrate!" << std::endl; + m_bIsBaudRateSet = true; + } + else + { + std::cout << "[ERROR](DynamixelHandler::setBaudRate) Failed to change the baudrate!" << std::endl; + m_bIsBaudRateSet = false; + } + } + else + { + std::cout << "[ERROR](DynamixelHandler::setBaudRate) m_pPortHandler is null!" << std::endl; + m_bIsBaudRateSet = false; + } + return m_bIsBaudRateSet; +} + +void DynamixelHandler::setDeviceName(std::string sDeviceName) +{ + m_sDeviceName = sDeviceName; + m_bIsDeviceNameSet = true; + + if (nullptr != m_pPortHandler) + { + delete m_pPortHandler; + m_pPortHandler = nullptr; + } + + // Initialize PortHandler instance + m_pPortHandler = dynamixel::PortHandler::getPortHandler(m_sDeviceName.c_str()); +} + +void DynamixelHandler::setProtocolVersion(float fProtocolVersion) +{ + m_fProtocolVersion = fProtocolVersion; + m_bIsProtocolVersionSet = true; + + if (nullptr != m_pPacketHandler) + { + delete m_pPacketHandler; + m_pPacketHandler = nullptr; + } + + m_pPacketHandler = dynamixel::PacketHandler::getPacketHandler(m_fProtocolVersion); +} + +bool DynamixelHandler::readCurrentJointPosition(std::vector& vCurrentJointPosition) +{ + // Creates a vector of joint position + std::vector l_vCurrentJointPosition; + // Reads the current joint positions in motor command unit + bool bIsReadSuccessfull = this->readCurrentJointPosition(l_vCurrentJointPosition); + //std::cout << "l_vCurrentJointPosition= " << l_vCurrentJointPosition[0] << ", " << l_vCurrentJointPosition[1] << ", " << l_vCurrentJointPosition[2]<< std::endl; + + // q1 + vCurrentJointPosition.push_back(ROT_DIRECTION_Q1*convertJointCmdToAngle(l_vCurrentJointPosition[0])); + // qpen + vCurrentJointPosition.push_back(ROT_DIRECTION_QPEN*convertJointCmdToAngle(l_vCurrentJointPosition[1])); + // q2 + vCurrentJointPosition.push_back(ROT_DIRECTION_Q2*convertJointCmdToAngle(l_vCurrentJointPosition[2])); + + //std::cout << "vCurrentJointPosition= " << vCurrentJointPosition[0] << ", " << vCurrentJointPosition[1] << ", " << vCurrentJointPosition[2]<< std::endl; + + return bIsReadSuccessfull; +} + +bool DynamixelHandler::readCurrentJointPosition(std::vector& vCurrentJointPosition) +{ + bool bIsReadSuccessfull = false; + + for (unsigned int l_joint = 0; l_joint < NB_JOINTS; l_joint++) + { + int dxl_comm_result = COMM_TX_FAIL; // Communication result + uint8_t dxl_error = 0; + uint16_t dxl_present_position = 0; + + dxl_comm_result = m_pPacketHandler->read2ByteTxRx(m_pPortHandler, l_joint + 1, ADDR_XL320_PRESENT_POSITION, &dxl_present_position, &dxl_error); + if (dxl_comm_result != COMM_SUCCESS) + { + //std::cout << "[ERROR] " << m_pPacketHandler->getTxRxResult(dxl_comm_result) << std::endl; + bIsReadSuccessfull = false; + } + else if (dxl_error != 0) + { + //std::cout << "[ERROR] " << m_pPacketHandler->getRxPacketError(dxl_error) << std::endl; + bIsReadSuccessfull = false; + } + else + { + vCurrentJointPosition.push_back(dxl_present_position); + bIsReadSuccessfull = true; + } + } + + return bIsReadSuccessfull; +} + +bool DynamixelHandler::sendTargetJointPosition(std::vector& vTargetJointPosition) +{ + // Checks if the input vector has the right size + if (vTargetJointPosition.size() != NB_JOINTS) + { + std::cout << "[ERROR] (sendTargetJointPosition) Input vector has not the right size!" << std::endl; + return false; + } + + // Creates a vector of motor commands + std::vector l_vTargetJointPosition; + // q1 + l_vTargetJointPosition.push_back(convertAngleToJointCmd(ROT_DIRECTION_Q1*vTargetJointPosition[0])); + // qpen + l_vTargetJointPosition.push_back(convertAngleToJointCmd(ROT_DIRECTION_QPEN*vTargetJointPosition[1])); + // q2 + l_vTargetJointPosition.push_back(convertAngleToJointCmd(ROT_DIRECTION_Q2*vTargetJointPosition[2])); + + //std::cout << "l_vTargetJointPosition= " << l_vTargetJointPosition[0] << ", " << l_vTargetJointPosition[1] << ", " << l_vTargetJointPosition[2]<< std::endl; + + // call the dxl sendTargetJointPosition + bool bIsSendSuccessfull = this->sendTargetJointPosition(l_vTargetJointPosition); + + return bIsSendSuccessfull; +} + +bool DynamixelHandler::sendTargetJointPosition(std::vector& vTargetJointPosition) +{ + bool bIsSendSuccessfull = false; + + // checks if the vector size is correct + if (vTargetJointPosition.size() != NB_JOINTS) + { + std::cout << "[ERROR] (DynamixelHandler::sendTargetJointPosition): Size of command vector is not correct: " << vTargetJointPosition.size() << " instead of " << NB_JOINTS << "!" << std::endl; + bIsSendSuccessfull = false; + } + + for (unsigned int l_joint = 0; l_joint < NB_JOINTS; l_joint++) + { + int dxl_comm_result = COMM_TX_FAIL; // Communication result + uint8_t dxl_error = 0; + uint16_t dxl_present_position = 0; + dxl_comm_result = m_pPacketHandler->write2ByteTxRx(m_pPortHandler, l_joint + 1, ADDR_XL320_GOAL_POSITION, vTargetJointPosition[l_joint], &dxl_error); + if (dxl_comm_result != COMM_SUCCESS) + { + //std::cout << "[ERROR] (DynamixelHandler::sendTargetJointPosition): " << m_pPacketHandler->getTxRxResult(dxl_comm_result) << std::endl; + bIsSendSuccessfull = false; + } + else if (dxl_error != 0) + { + //std::cout << "[ERROR] (DynamixelHandler::sendTargetJointPosition): " << m_pPacketHandler->getRxPacketError(dxl_error) << std::endl; + bIsSendSuccessfull = false; + } + else + { + bIsSendSuccessfull = true; + } + } + return bIsSendSuccessfull; + +} + +bool DynamixelHandler::sendTargetJointVelocity(std::vector& vTargetJointVelocity) +{ + // Checks if the input vector has the right size + if (vTargetJointVelocity.size() != NB_JOINTS) + { + std::cout << "[ERROR] (sendTargetJointVelocity) Input vector has not the right size!" << std::endl; + return false; + } + + // Creates a vector of motor commands + std::vector l_vTargetJointVelocity; + // q1 + l_vTargetJointVelocity.push_back(convertJointVelocityToJointCmd(ROT_DIRECTION_Q1*vTargetJointVelocity[0])); + // qpen + l_vTargetJointVelocity.push_back(convertJointVelocityToJointCmd(ROT_DIRECTION_QPEN*vTargetJointVelocity[1])); + // q2 + l_vTargetJointVelocity.push_back(convertJointVelocityToJointCmd(ROT_DIRECTION_Q2*vTargetJointVelocity[2])); + + std::cout << "l_vTargetJointVelocity= " << l_vTargetJointVelocity[0] << ", " << l_vTargetJointVelocity[1] << ", " << l_vTargetJointVelocity[2]<< std::endl; + + // call the dxl sendTargetJointPosition + bool bIsSendSuccessfull = this->sendTargetJointVelocity(l_vTargetJointVelocity); + + return bIsSendSuccessfull; +} + +bool DynamixelHandler::sendTargetJointVelocity(std::vector& vTargetJointVelocity) +{ + bool bIsSendSuccessfull = false; + + // checks if the vector size is correct + if (vTargetJointVelocity.size() != NB_JOINTS) + { + std::cout << "[ERROR] (DynamixelHandler::sendTargetJointVelocity): Size of command vector is not correct: " << vTargetJointVelocity.size() << " instead of " << NB_JOINTS << "!" << std::endl; + bIsSendSuccessfull = false; + } + + for (unsigned int l_joint = 0; l_joint < NB_JOINTS; l_joint++) + { + int dxl_comm_result = COMM_TX_FAIL; // Communication result + uint8_t dxl_error = 0; + uint16_t dxl_present_position = 0; + dxl_comm_result = m_pPacketHandler->write2ByteTxRx(m_pPortHandler, l_joint + 1, ADDR_XL320_GOAL_VELOCITY, vTargetJointVelocity[l_joint], &dxl_error); + if (dxl_comm_result != COMM_SUCCESS) + { + //std::cout << "[ERROR] (DynamixelHandler::sendTargetJointPosition): " << m_pPacketHandler->getTxRxResult(dxl_comm_result) << std::endl; + bIsSendSuccessfull = false; + } + else if (dxl_error != 0) + { + //std::cout << "[ERROR] (DynamixelHandler::sendTargetJointPosition): " << m_pPacketHandler->getRxPacketError(dxl_error) << std::endl; + bIsSendSuccessfull = false; + } + else + { + bIsSendSuccessfull = true; + } + } + return bIsSendSuccessfull; + +} + +bool DynamixelHandler::enableTorque(bool bEnableTorque) +{ + bool bIsSendSuccessfull = false; + + for (unsigned int l_joint = 0; l_joint < NB_JOINTS; l_joint++) + { + int dxl_comm_result = COMM_TX_FAIL; // Communication result + uint8_t dxl_error = 0; + + dxl_comm_result = m_pPacketHandler->write1ByteTxRx(m_pPortHandler, l_joint + 1, ADDR_XL320_TORQUE_ENABLE, bEnableTorque, &dxl_error); + if (dxl_comm_result != COMM_SUCCESS) + { + //std::cout << "[ERROR] (DynamixelHandler::enableTorque): " << m_pPacketHandler->getTxRxResult(dxl_comm_result) << std::endl; + bIsSendSuccessfull = false; + } + else if (dxl_error != 0) + { + //std::cout << "[ERROR] (DynamixelHandler::enableTorque): " << m_pPacketHandler->getRxPacketError(dxl_error) << std::endl; + bIsSendSuccessfull = false; + } + else + { + bIsSendSuccessfull = true; + } + } + return bIsSendSuccessfull; +} + +bool DynamixelHandler::setControlMode(int iControlMode) +{ + bool bIsSendSuccessfull = false; + + for (unsigned int l_joint = 0; l_joint < NB_JOINTS; l_joint++) + { + int dxl_comm_result = COMM_TX_FAIL; // Communication result + uint8_t dxl_error = 0; + + dxl_comm_result = m_pPacketHandler->write1ByteTxRx(m_pPortHandler, l_joint + 1, ADDR_XL320_CONTROL_MODE, iControlMode, &dxl_error); + if (dxl_comm_result != COMM_SUCCESS) + { + //std::cout << "[ERROR] (DynamixelHandler::enableTorque): " << m_pPacketHandler->getTxRxResult(dxl_comm_result) << std::endl; + bIsSendSuccessfull = false; + } + else if (dxl_error != 0) + { + //std::cout << "[ERROR] (DynamixelHandler::enableTorque): " << m_pPacketHandler->getRxPacketError(dxl_error) << std::endl; + bIsSendSuccessfull = false; + } + else + { + bIsSendSuccessfull = true; + } + } + return bIsSendSuccessfull; +} diff --git a/src/Kinematics.cpp b/src/Kinematics.cpp new file mode 100644 index 0000000..db043c4 --- /dev/null +++ b/src/Kinematics.cpp @@ -0,0 +1,161 @@ +#include "Kinematics.h" + + +float deg2rad(float angle) +{ + return angle/180.0*M_PI; +} + +float rad2deg(float angle) +{ + return angle*180.0/M_PI; +} + +std::vector computeForwardKinematics(float q1, float q2, float L1, float L2) +{ + float x = L1 * cos(q1) + L2 * cos(q1+q2); + float y = L1 * sin(q1) + L2 * sin(q1+q2); + std::cout << "[INFO] Forward Kinematics : (q1, q2)->(x, y) = (" << rad2deg(q1) << ", " << rad2deg(q2) << ")->(" << x << ", " << y << ")" << std::endl; + std::vector X; + X.push_back(x); + X.push_back(y); + + return X; +} + +std::vector computeInverseKinematics(float x, float y, float L1, float L2) +{ + std::vector qi; + + float cos_q2 = (x*x+y*y-(L1*L1+L2*L2)) / (2.0 * L1 * L2); + + std::cout << "[INFO] cos_q2= " << cos_q2 << std::endl; + + if (cos_q2 >1 | cos_q2 <-1) + { + qi.push_back(0.0); + std::cout << "[INFO] Inverse Kinematics: No solution!" << std::endl; + } + else if (cos_q2 == 1) + { + qi.push_back(1.0); + float q1 = atan2(y, x); + float q2 = 0; + std::cout << "[INFO] Inverse Kinematics: One solution: (x, y)->(q1, q2) = (" << x << ", " << y << ")->(" << rad2deg(q1) << ", " << rad2deg(q2) << ")" << std::endl; + qi.push_back(q1); + qi.push_back(q2); + } + else if (cos_q2 == -1) + { + qi.push_back(1.0); + float q1 = atan2(y, x); + float q2 = M_PI; + std::cout << "[INFO] Inverse Kinematics: One solution: (x, y)->(q1, q2) = (" << x << ", " << y << ")->(" << rad2deg(q1) << ", " << rad2deg(q2) << ")" << std::endl; + qi.push_back(q1); + qi.push_back(q2); + } + else + { + qi.push_back(2.0); + std::cout << "[INFO] Inverse Kinematics: Two solutions: "<< std::endl; + + float q2 = acos(cos_q2); + float q1 = (float)(atan2(y, x) - atan2(L2*sin(q2), L1+L2*cos_q2)); + std::cout << "\t(x, y)->(q1, q2) = (" << x << ", " << y << ")->(" << rad2deg(q1) << ", " << rad2deg(q2) << ")" << std::endl; + qi.push_back(q1); + qi.push_back(q2); + + + q2 = -acos(cos_q2); + q1 = (float)(atan2(y, x) - atan2(L2*sin(q2), L1+L2*cos_q2)); + + std::cout << "\t(x, y)->(q1, q2) = (" << x << ", " << y << ")->(" << rad2deg(q1) << ", " << rad2deg(q2) << ")" << std::endl; + qi.push_back(q1); + qi.push_back(q2); + } + + return qi; +} + +std::vector computeDifferentialKinematics(float q1, float q2, float L1, float L2) +{ + std::vector jacobian; + + float j11 = -L2*sin(q1+q2) - L1*sin(q1); + float j12 = -L2*sin(q1+q2); + float j21 = L2*cos(q1+q2) + L1*cos(q1); + float j22 = L2*cos(q1+q2); + + jacobian.push_back(j11); + jacobian.push_back(j12); + jacobian.push_back(j21); + jacobian.push_back(j22); + + return jacobian; +} + +int computeJacobianMatrixRank(std::vector vJacobianMatrix, float threshold) +{ + int rank = -1; + cv::Mat1f oJacobianMatrix(2, 2); + + if (vJacobianMatrix.size() == 4) + { + // Converts the Jacobian matrix from std::vector to cv::Mat + oJacobianMatrix.at(0, 0) = vJacobianMatrix[0]; + oJacobianMatrix.at(0, 1) = vJacobianMatrix[1]; + oJacobianMatrix.at(1, 0) = vJacobianMatrix[2]; + oJacobianMatrix.at(1, 1) = vJacobianMatrix[3]; + std::cout << "=====Jacobian Matrix=====" << std::endl; + std::cout << "[ " << oJacobianMatrix.at(0,0) << ", " << oJacobianMatrix.at(0,1) << " ]" << std::endl; + std::cout << "[ " << oJacobianMatrix.at(1,0) << ", " << oJacobianMatrix.at(1,1) << " ]" << std::endl; + // Computes the determinant of the Jacobian matrix + float determinant = abs(vJacobianMatrix[0] * vJacobianMatrix[3] - vJacobianMatrix[1]*vJacobianMatrix[2]); + std::cout << "=====Determinant of the Jacobian matrix=====" << std::endl << determinant << std::endl; + // Computes SVD + cv::Mat1f w, u, vt; + cv::SVD::compute(oJacobianMatrix, w, u, vt); + // Finds non zero singular values + cv::Mat1f nonZeroSingularValues = w/w.at(0,0) > threshold; + // Counts the number of non zero singular values + rank = cv::countNonZero(nonZeroSingularValues); + std::cout << "=====Rank of the Jacobian matrix=====" << std::endl << rank << " / " << oJacobianMatrix.rows << std::endl; + // Determines the inverse of the Jacobian matrix + cv::Mat oJacobianInverse = oJacobianMatrix.inv(); + std::cout << "=====Inverse of the Jacobian Matrix=====" << std::endl; + std::cout << "[ " << oJacobianInverse.at(0,0) << ", " << oJacobianInverse.at(0,1) << " ]" << std::endl; + std::cout << "[ " << oJacobianInverse.at(1,0) << ", " << oJacobianInverse.at(1,1) << " ]" << std::endl; + } + else + std::cout << "[ERROR] Jacobian matrix has a size of "<< vJacobianMatrix.size() << " instead of 4" << std::endl; + + return rank; +} + +cv::Mat computeInverseJacobianMatrix(std::vector vJacobianMatrix) +{ + cv::Mat1f oJacobianMatrix(2, 2); + cv::Mat oJacobianInverse; + + if (vJacobianMatrix.size() == 4) + { + // Converts the Jacobian matrix from std::vector to cv::Mat + oJacobianMatrix.at(0, 0) = vJacobianMatrix[0]; + oJacobianMatrix.at(0, 1) = vJacobianMatrix[1]; + oJacobianMatrix.at(1, 0) = vJacobianMatrix[2]; + oJacobianMatrix.at(1, 1) = vJacobianMatrix[3]; + std::cout << "=====Jacobian Matrix=====" << std::endl; + std::cout << "[ " << oJacobianMatrix.at(0,0) << ", " << oJacobianMatrix.at(0,1) << " ]" << std::endl; + std::cout << "[ " << oJacobianMatrix.at(1,0) << ", " << oJacobianMatrix.at(1,1) << " ]" << std::endl; + // Determines the inverse of the Jacobian matrix + cv::invert(oJacobianMatrix, oJacobianInverse, cv::DECOMP_SVD); + //oJacobianInverse = oJacobianMatrix.inv(); + std::cout << "=====Inverse of the Jacobian Matrix=====" << std::endl; + std::cout << "[ " << oJacobianInverse.at(0,0) << ", " << oJacobianInverse.at(0,1) << " ]" << std::endl; + std::cout << "[ " << oJacobianInverse.at(1,0) << ", " << oJacobianInverse.at(1,1) << " ]" << std::endl; + } + else + std::cout << "[ERROR] Jacobian matrix has a size of "<< vJacobianMatrix.size() << " instead of 4" << std::endl; + + return oJacobianInverse; +} \ No newline at end of file diff --git a/src/RedBallDetection.cpp b/src/RedBallDetection.cpp index 4b92ed6..d7d97ef 100644 --- a/src/RedBallDetection.cpp +++ b/src/RedBallDetection.cpp @@ -10,8 +10,8 @@ #include #define CAM_PARAMS_FILENAME "./data/camera_calibration_params.xml" -//#define COLOR_PARAMS_FILENAME "./data/color_params.xml" -#define COLOR_PARAMS_FILENAME "./data/color_params_RGB.xml" +#define COLOR_PARAMS_FILENAME "./data/color_params.xml" +//#define COLOR_PARAMS_FILENAME "./data/color_params_RGB.xml" #define FPS 30.0 #define STRUCTURAL_ELEMENTS_SIZE 5 #define RESOLUTION_MAX 800 @@ -31,8 +31,8 @@ bool readCameraParameters(std::string filename, cv::Mat &camMatrix, cv::Mat & di return true; } -//bool writeColorParameters(std::string filename, int iLowH, int iHighH, int iLowS, int iHighS, int iLowV, int iHighV) -bool writeColorParameters(std::string filename, int iLowR, int iHighR, int iLowG, int iHighG, int iLowB, int iHighB) +bool writeColorParameters(std::string filename, int iLowH, int iHighH, int iLowS, int iHighS, int iLowV, int iHighV) +//bool writeColorParameters(std::string filename, int iLowR, int iHighR, int iLowG, int iHighG, int iLowB, int iHighB) { cv::FileStorage fs(filename, cv::FileStorage::WRITE); if (!fs.isOpened()) @@ -41,7 +41,7 @@ bool writeColorParameters(std::string filename, int iLowR, int iHighR, int iLowG return false; } - /* + fs << "lowH" << iLowH; fs << "highH" << iHighH; @@ -52,7 +52,7 @@ bool writeColorParameters(std::string filename, int iLowR, int iHighR, int iLowG fs << "lowV" << iLowV; fs << "highV" << iHighV; - */ + /* fs << "lowR" << iLowR; fs << "highR" << iHighR; @@ -62,7 +62,7 @@ bool writeColorParameters(std::string filename, int iLowR, int iHighR, int iLowG fs << "lowB" << iLowB; fs << "highB" << iHighB; - + */ // releases the writer fs.release(); @@ -141,7 +141,7 @@ int main(int argc, char** argv) cv::namedWindow("Control", cv::WINDOW_AUTOSIZE); //create a window called "Control" // sets min/max value for HSV color representation - /* + int iLowH = 0; int iHighH = 179; @@ -150,7 +150,7 @@ int main(int argc, char** argv) int iLowV = 0; int iHighV = 255; - */ + /* int iLowR = 0; int iHighR = 255; @@ -159,7 +159,8 @@ int main(int argc, char** argv) int iLowB = 0; int iHighB = 255; -/* + */ + // creates trackbars in "Control" window cv::createTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179) cv::createTrackbar("HighH", "Control", &iHighH, 179); @@ -169,7 +170,7 @@ int main(int argc, char** argv) cv::createTrackbar("LowV", "Control", &iLowV, 255); //Value (0 - 255) cv::createTrackbar("HighV", "Control", &iHighV, 255); - */ + /* // creates trackbars in "Control" window cv::createTrackbar("LowR", "Control", &iLowR, 255); //Red (0 - 255) cv::createTrackbar("HighR", "Control", &iHighR, 255); @@ -179,7 +180,7 @@ int main(int argc, char** argv) cv::createTrackbar("LowB", "Control", &iLowB, 255); //Blue (0 - 255) cv::createTrackbar("HighB", "Control", &iHighB, 255); - + */ while (true) @@ -206,8 +207,8 @@ int main(int argc, char** argv) //Threshold the image based on the trackbar values cv::Mat imgThresholded; - //inRange(imgHSV, cv::Scalar(iLowH, iLowS, iLowV), cv::Scalar(iHighH, iHighS, iHighV), imgThresholded); - inRange(imgOriginal, cv::Scalar(iLowR, iLowG, iLowB), cv::Scalar(iHighR, iHighG, iHighB), imgThresholded); + inRange(imgHSV, cv::Scalar(iLowH, iLowS, iLowV), cv::Scalar(iHighH, iHighS, iHighV), imgThresholded); + //inRange(imgOriginal, cv::Scalar(iLowR, iLowG, iLowB), cv::Scalar(iHighR, iHighG, iHighB), imgThresholded); //morphological opening (remove small objects from the foreground) cv::erode(imgThresholded, imgThresholded, cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(iStructuralElementSize, iStructuralElementSize)) ); @@ -236,8 +237,8 @@ int main(int argc, char** argv) } if (key == 's') { - //writeColorParameters(sColorParamFilename, iLowH, iHighH, iLowS, iHighS, iLowV, iHighV); - writeColorParameters(sColorParamFilename, iLowR, iHighR, iLowG, iHighG, iLowB, iHighB); + writeColorParameters(sColorParamFilename, iLowH, iHighH, iLowS, iHighS, iLowV, iHighV); + //writeColorParameters(sColorParamFilename, iLowR, iHighR, iLowG, iHighG, iLowB, iHighB); std::cout << "[INFO] Color parameters saved to file: " << sColorParamFilename << std::endl; } diff --git a/src/RobotServoing.cpp b/src/RobotServoing.cpp new file mode 100644 index 0000000..7a348d5 --- /dev/null +++ b/src/RobotServoing.cpp @@ -0,0 +1,321 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include + +#include "Kinematics.h" +#include "DynamixelHandler.h" + +#define CAM_PARAMS_FILENAME "./data/camera_calibration_params.xml" +#define COLOR_PARAMS_FILENAME "./data/color_params_data.xml" +#define FPS 30.0 +#define STRUCTURAL_ELEMENTS_SIZE 5 +#define AREA_THRESOLD 1000 +#define ROBOT_L1 5 +#define ROBOT_L2 6 +#define HEIGHT2CM 13.63 +#define WIDTH2CM 13.49 +#define RESOLUTION_MAX 800 + +using namespace cv; +using namespace std; + +DynamixelHandler _oDxlHandler; +std::string _robotDxlPortName = "/dev/ttyUSB0"; +float _robotDxlProtocol = 2.0; +int _robotDxlBaudRate = 1000000; + + +void initRobot(DynamixelHandler& dxlHandler, std::string portName, float protocol, int baudRate) +{ + std::cout << "===Initialization of the Dynamixel Motor communication====" << std::endl; + dxlHandler.setDeviceName(portName); + dxlHandler.setProtocolVersion(protocol); + dxlHandler.openPort(); + dxlHandler.setBaudRate(baudRate); + dxlHandler.enableTorque(true); + std::cout << std::endl; +} + +void closeRobot(DynamixelHandler& dxlHandler) +{ + dxlHandler.enableTorque(false); + dxlHandler.closePort(); +} + +bool readCameraParameters(std::string filename, cv::Mat &camMatrix, cv::Mat & distCoeffs) +{ + cv::FileStorage fs(filename, cv::FileStorage::READ); + if (!fs.isOpened()) + { + std::cout << "[ERROR] Could not open the camera parameter file storage: " << filename << " !"<< std::endl; + return false; + } + + fs["camera_matrix"] >> camMatrix; + fs["distortion_coefficients"] >> distCoeffs; + + return true; +} + +bool readColorParameters(std::string filename, int& iLowH, int& iHighH, int& iLowS, int& iHighS, int& iLowV, int& iHighV) +{ + cv::FileStorage fs(filename, cv::FileStorage::READ); + if (!fs.isOpened()) + { + std::cout << "[ERROR] Could not open the color paramter file storage: " << filename << " !"<< std::endl; + return false; + } + + fs["lowH"] >> iLowH; + fs["highH"] >> iHighH; + + fs["lowS"] >> iLowS; + fs["highS"] >> iHighS; + + fs["lowV"] >> iLowV; + fs["highV"] >> iHighV; + + return true; +} + + +int main(int argc, char** argv) +{ + // initializes main parameters + float L1 = ROBOT_L1; + float L2 = ROBOT_L2; + float qpen = deg2rad(-90); // in rad + std::string sCameraParamFilename = CAM_PARAMS_FILENAME; + std::string sColorParamFilename = COLOR_PARAMS_FILENAME; + float fFPS = FPS; + int iStructuralElementSize = STRUCTURAL_ELEMENTS_SIZE; + int iAreaThresold = AREA_THRESOLD; + int iMaxVideoResolution = RESOLUTION_MAX; + + // updates main parameters from arguments + int opt; + while ((opt = getopt (argc, argv, ":c:f:s:a:i:p:l:m:r:")) != -1) + { + switch (opt) + { + case 'c': + sColorParamFilename = optarg; + break; + case 'f': + fFPS = atof(optarg); + break; + case 'p': + qpen = atof(optarg); + break; + case 'l': + L1 = atof(optarg); + break; + case 'm': + L2 = atof(optarg); + break; + case 's': + iStructuralElementSize = atoi(optarg); + break; + case 'a': + iAreaThresold = atoi(optarg); + break; + case 'i': + sCameraParamFilename = optarg; + break; + case 'r': + iMaxVideoResolution = atoi(optarg); + break; + case '?': + if (optopt == 'c' || optopt == 'f' || optopt == 's' || optopt == 'a' || optopt == 'p' || optopt == 'l' || optopt == 'm' || optopt == 'i' || optopt == 'r') + fprintf (stderr, "Option -%c requires an argument.\n", optopt); + else if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); + return 1; + default: + abort (); + } + } + + // Initializes the robot + initRobot(_oDxlHandler, _robotDxlPortName, _robotDxlProtocol, _robotDxlBaudRate); + + + // reads color parameters from the file storage + int iLowH, iHighH, iLowS, iHighS, iLowV, iHighV; + bool isColorParamsSet = readColorParameters(sColorParamFilename, iLowH, iHighH, iLowS, iHighS, iLowV, iHighV); + + // checks if the color parameters were successfully read + if (!isColorParamsSet) + { + std::cout << "[ERROR] Color parameters could not be loaded!" << std::endl; + return -1; + } + + // distorted/undistorted image + bool bIsImageUndistorted = true; + + // reads camera intrinsic parameters + cv::Mat cameraMatrix, distCoeffs; + bool isCamParamsSet = readCameraParameters(sCameraParamFilename, cameraMatrix, distCoeffs); + + // checks if the camera parameters were successfully read + if (!isCamParamsSet) + { + std::cout << "[WARNING] Camera intrinsic parameters could not be loaded!" << std::endl; + } + + // creates a camera grabber + VideoCapture cap(0, cv::CAP_V4L2); //capture the video from webcam + + // changes image resolution to maximum (e.g. 1920x1080 if possible) + cap.set(cv::CAP_PROP_FRAME_HEIGHT, iMaxVideoResolution); cap.set(cv::CAP_PROP_FRAME_WIDTH, iMaxVideoResolution); + + // checks if the camera was successfully opened + if ( !cap.isOpened() ) // if not success, exit program + { + cout << "[ERROR] Could not open the camera!" << endl; + return -1; + } + + // inits previous x,y location of the ball + int iLastX = -1; + int iLastY = -1; + + // captures a temporary image from the camera + Mat imgTmp; + cap.read(imgTmp); + + // main loop launched every FPS + while (true) + { + // creates a black image with the size as the camera output + Mat imgLines = Mat::zeros( imgTmp.size(), CV_8UC3 ); + + // reads a new frame from video + cv::Mat imgOriginal; + bool bSuccess = cap.read(imgOriginal); + + // checks if a new frame was grabbed + if (!bSuccess) //if not success, break loop + { + std::cout << "[WARNING] Could not read a new frame from video stream" << std::endl; + break; + } + + if (bIsImageUndistorted && isCamParamsSet) + { + cv::Mat temp = imgOriginal.clone(); + cv::undistort(temp, imgOriginal, cameraMatrix, distCoeffs); + } + + // converts the captured frame from BGR to HSV + cv::Mat imgHSV; + cvtColor(imgOriginal, imgHSV, cv::COLOR_BGR2HSV); + + // thresholds the image based on the trackbar values + cv::Mat imgThresholded; + inRange(imgHSV, cv::Scalar(iLowH, iLowS, iLowV), cv::Scalar(iHighH, iHighS, iHighV), imgThresholded); + + // applies morphological opening (removes small objects from the foreground) + cv::erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(iStructuralElementSize, iStructuralElementSize)) ); + cv::dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(iStructuralElementSize, iStructuralElementSize)) ); + + // applies morphological closing (removes small holes from the foreground) + cv::dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(iStructuralElementSize, iStructuralElementSize)) ); + cv::erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(iStructuralElementSize, iStructuralElementSize)) ); + + // calculates the moments of the thresholded image + Moments oMoments = moments(imgThresholded); + double dM01 = oMoments.m01; + double dM10 = oMoments.m10; + double dArea = oMoments.m00; + + // if the area <= iAreaThresold, considers that the there are no object in the image and it's because of the noise, the area is not zero + int posX, posY; + + if (dArea > iAreaThresold) + { + // calculates the position of the ball + posX = dM10 / dArea; + posY = dM01 / dArea; + + if (iLastX >= 0 && iLastY >= 0 && posX >= 0 && posY >= 0) + { + // draww a red line from the previous point to the current point + line(imgLines, Point(posX, posY), Point(iLastX, iLastY), Scalar(0,0,255), 2); + } + + // stores the current position for enxt frame + iLastX = posX; + iLastY = posY; + } + + // displays the thresholded image + imshow("Thresholded Image", imgThresholded); + + // adds a cross at the centre of the image + cv::drawMarker(imgOriginal, cv::Point(imgTmp.size().width/2, imgTmp.size().height/2), 10, cv::MARKER_CROSS, cv::LINE_8); + + // shows the original image with the tracking (red) lines + imgOriginal = imgOriginal + imgLines; + imshow("Original", imgOriginal); + + // converts posX, posY in mm in the world reference frame + float img_width = imgTmp.size().width; + float img_height = imgTmp.size().height; + float x = (posY-img_height/2)/img_height*HEIGHT2CM; + float y = (posX-img_width/2)/img_width*WIDTH2CM; + + std::cout << "(pixel -> cm) = (" << posX << ", " << posY << ") - > (" << x << ", " << y << ")" << std::endl; + + // Computes IK + std::vector qi = computeInverseKinematics(x, y, L1, L2); + + // Computes FK + //computeForwardKinematics(qi[1], qi[2], L1, L2); + + // Sends the target joint values received only if there is at least a solution + if (qi.size() >= 3) + { + std::vector vTargetJointPosition; + vTargetJointPosition.push_back(qi[1]); + vTargetJointPosition.push_back(qpen); + vTargetJointPosition.push_back(qi[2]); + _oDxlHandler.sendTargetJointPosition(vTargetJointPosition); + } + + // waits for awhile depending on the FPS value + char key = (char)cv::waitKey(1000.0/fFPS); + // checks if ESC was pressed to exit + if (key == 27) // if 'esc' key is pressed, break loop + { + std::cout << "[INFO] esc key is pressed by user -> Shutting down!" << std::endl; + break; + } + if (key == 'u') + { + bIsImageUndistorted = !bIsImageUndistorted; + std::cout << "[INFO] Image undistorted: " << bIsImageUndistorted<< std::endl; + } + } + + + + + + + // Closes robot connection + _oDxlHandler.closePort(); + + return 0; +}