Browse Source

运动学模块调整、灵活工作空间辨别

Walker 1 năm trước cách đây
mục cha
commit
6505e789fa

+ 58 - 12
SourceCode/Deprecated/RUS/SourceCode/OnGoingTasks/ForceControl/Demo/ForceControl/MainWindow.xaml.cs

@@ -224,6 +224,9 @@ namespace ForceControl
         private EnumAdmittanceType _admittanceType;
 
         private List<string> _logList1 = new List<string>();
+        private List<string> _logList2 = new List<string>();
+        private List<string> _logList3 = new List<string>();
+        private List<string> _logList4 = new List<string>();
 
         // 创建一个 ManualResetEvent 对象
         private static ManualResetEvent _waitEvent = new ManualResetEvent(false);
@@ -1035,6 +1038,33 @@ namespace ForceControl
 
                 _sensorInfo = new FTSensorInformation();
 
+                StreamWriter streamWriter1 = new StreamWriter("FTSensorRaw.txt");
+                foreach (string str in _logList1)
+                {
+                    streamWriter1.WriteLine(str);
+                }
+                streamWriter1.Close();
+
+                StreamWriter streamWriter2 = new StreamWriter("FTAnalyserUpdate.txt");
+                foreach (string str in _logList2)
+                {
+                    streamWriter2.WriteLine(str);
+                }
+                streamWriter2.Close();
+
+                StreamWriter streamWriter3 = new StreamWriter("FTEndToolData.txt");
+                foreach (string str in _logList3)
+                {
+                    streamWriter3.WriteLine(str);
+                }
+                streamWriter3.Close();
+
+                StreamWriter streamWriter4 = new StreamWriter("FTCallBackUpdate.txt");
+                foreach (string str in _logList4)
+                {
+                    streamWriter4.WriteLine(str);
+                }
+                streamWriter4.Close();
                 BtnConnectFTSensor.Content = "连接传感器";
                 ComboBoxFTSensorType.IsEnabled = true;
             }
@@ -1679,6 +1709,14 @@ namespace ForceControl
             _sensorRaw = e.FTData;
             _sensorRawUpdated = true;
             _sensorRawQueue.Enqueue(e.FTData);
+            _logList1.Add(DateTime.Now.ToString("HH:mm:ss.fff") + " " +
+                e.FTData.Index.ToString() + " " +
+                e.FTData.CartFT.GenForce[0].ToString() + " " +
+                e.FTData.CartFT.GenForce[1].ToString() + " " +
+                e.FTData.CartFT.GenForce[2].ToString() + " " +
+                e.FTData.CartFT.GenForce[3].ToString() + " " +
+                e.FTData.CartFT.GenForce[4].ToString() + " " +
+                e.FTData.CartFT.GenForce[5].ToString());
         }
 
         private void OnSensorFTUpdate(object sender, FTDataUpdateEventArgs e)
@@ -1693,6 +1731,14 @@ namespace ForceControl
             _endToolFT = e.FTData;
             _endToolFTUpdated = true;
             _endToolFTQueue.Enqueue(e.FTData);
+            _logList3.Add(DateTime.Now.ToString("HH:mm:ss.fff") + " " +
+                e.FTData.Index.ToString() + " " +
+                e.FTData.CartFT.GenForce[0].ToString() + " " +
+                e.FTData.CartFT.GenForce[1].ToString() + " " +
+                e.FTData.CartFT.GenForce[2].ToString() + " " +
+                e.FTData.CartFT.GenForce[3].ToString() + " " +
+                e.FTData.CartFT.GenForce[4].ToString() + " " +
+                e.FTData.CartFT.GenForce[5].ToString());
         }
 
         /// <summary>
@@ -2121,18 +2167,18 @@ namespace ForceControl
                 wayPtsList.Add(wayPt);
                 //wayptOld = wayPt;
             }
-            string filePath = "F:\\wayPt\\jointAngleOutput.txt";
-            using (StreamWriter writer = new StreamWriter(filePath))
-            {
-                foreach (var RobotWayPointData in wayPtsList)
-                {
-                    foreach (double number in RobotWayPointData.JointPos.JointAngle)
-                    {
-                        writer.Write(number + "\t"); // 写入每个 double 值,用\t分隔
-                    }
-                    writer.WriteLine(); // 每个数组写入文件后换行
-                }
-            }
+            //string filePath = "F:\\wayPt\\jointAngleOutput.txt";
+            //using (StreamWriter writer = new StreamWriter(filePath))
+            //{
+            //    foreach (var RobotWayPointData in wayPtsList)
+            //    {
+            //        foreach (double number in RobotWayPointData.JointPos.JointAngle)
+            //        {
+            //            writer.Write(number + "\t"); // 写入每个 double 值,用\t分隔
+            //        }
+            //        writer.WriteLine(); // 每个数组写入文件后换行
+            //    }
+            //}
         }
 
         /// <summary>

+ 10 - 10
SourceCode/Deprecated/RUS/SourceCode/OnGoingTasks/TrajectoryPlanning/Demo/TrajectoryPlanningDemo.sln

@@ -38,8 +38,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PCLPathGeneratorLib", "..\.
 		{79CA2EAF-C5BE-4E23-B265-AFFBF5D2B2D5} = {79CA2EAF-C5BE-4E23-B265-AFFBF5D2B2D5}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TrajectoryPlanning", "..\..\..\..\..\..\Git_Andrew_new\RUS\SourceCode\RUSTasks\TaskTrajectoryPlanning\TrajectoryPlanning\TrajectoryPlanning.vcxproj", "{5E5F28D6-274E-4A66-8782-6FD27258503D}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RCIWrapper", "..\..\..\RUSTasks\TaskRobotModule\RCIWrapper\RCIWrapper.vcxproj", "{18DBEC76-414C-4B9F-B7C4-4E5C1F64C0D9}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SRSKinematics", "..\..\..\RUSTasks\TaskKinematics\SRSKinematics\SRSKinematics.vcxproj", "{034A2104-44C2-4254-BD63-8B7499422188}"
@@ -56,6 +54,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PCLPathGeneratorUtils", "..
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VTKRenderUtils", "..\..\..\RUSTasks\TaskVTKRenderTool\VTKRenderUtils\VTKRenderUtils.vcxproj", "{E548F0D7-A37B-4C22-9FE7-74AAC420D172}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TrajectoryPlanning", "..\..\..\RUSTasks\TaskTrajectoryPlanning\TrajectoryPlanning\TrajectoryPlanning.vcxproj", "{5E5F28D6-274E-4A66-8782-6FD27258503D}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -151,14 +151,6 @@ Global
 		{F1A37B69-D038-4129-BBA5-C84DC89BDA05}.Release|Any CPU.Build.0 = Release|Any CPU
 		{F1A37B69-D038-4129-BBA5-C84DC89BDA05}.Release|x64.ActiveCfg = Release|x64
 		{F1A37B69-D038-4129-BBA5-C84DC89BDA05}.Release|x64.Build.0 = Release|x64
-		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Debug|Any CPU.ActiveCfg = Debug|x64
-		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Debug|Any CPU.Build.0 = Debug|x64
-		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Debug|x64.ActiveCfg = Debug|x64
-		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Debug|x64.Build.0 = Debug|x64
-		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Release|Any CPU.ActiveCfg = Release|x64
-		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Release|Any CPU.Build.0 = Release|x64
-		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Release|x64.ActiveCfg = Release|x64
-		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Release|x64.Build.0 = Release|x64
 		{18DBEC76-414C-4B9F-B7C4-4E5C1F64C0D9}.Debug|Any CPU.ActiveCfg = Debug|x64
 		{18DBEC76-414C-4B9F-B7C4-4E5C1F64C0D9}.Debug|Any CPU.Build.0 = Debug|x64
 		{18DBEC76-414C-4B9F-B7C4-4E5C1F64C0D9}.Debug|x64.ActiveCfg = Debug|x64
@@ -223,6 +215,14 @@ Global
 		{E548F0D7-A37B-4C22-9FE7-74AAC420D172}.Release|Any CPU.Build.0 = Release|x64
 		{E548F0D7-A37B-4C22-9FE7-74AAC420D172}.Release|x64.ActiveCfg = Release|x64
 		{E548F0D7-A37B-4C22-9FE7-74AAC420D172}.Release|x64.Build.0 = Release|x64
+		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Debug|Any CPU.ActiveCfg = Debug|x64
+		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Debug|Any CPU.Build.0 = Debug|x64
+		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Debug|x64.ActiveCfg = Debug|x64
+		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Debug|x64.Build.0 = Debug|x64
+		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Release|Any CPU.ActiveCfg = Release|x64
+		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Release|Any CPU.Build.0 = Release|x64
+		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Release|x64.ActiveCfg = Release|x64
+		{5E5F28D6-274E-4A66-8782-6FD27258503D}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 10 - 0
SourceCode/Deprecated/RUS/SourceCode/RUSTasks/TaskKinematics/Kinematics/EnumInverseKinematicsMethod.cs

@@ -0,0 +1,10 @@
+namespace KinematicsLib
+{
+    public enum EnumInverseKinematicsMethod
+    {
+        // 根据最近邻关节角返回逆解
+        NearestNeighborAngle = 0,
+        // 根据关节角4和关节角6的正负返回逆解
+        PositiveNegativeAngle
+    };
+}

+ 147 - 0
SourceCode/Deprecated/RUS/SourceCode/RUSTasks/TaskPCLDataPreprocess/PCLPreprocessUtils/PCLInWorkSpace.cpp

@@ -0,0 +1,147 @@
+#include "CommonFunction.h"
+#include "PCLInWorkSpace.h"
+#include "../../Common/logger/RusLog.h"
+
+// 设置Log目录和文件
+bool logDirectorySetWorkSpace = false;
+void SetLogDirectoryAndFileWorkSpace()
+{
+    if (!logDirectorySetWorkSpace)
+    {
+        SetLogFileDirectory("F:/RUSLog/WorkSpaceLog");
+        SetLogFileName("WorkSpace");
+        SetLogLevel(RUS_LOG_WARNING);
+        EnableLogFile(true);
+        logDirectorySetWorkSpace = true;
+    }
+}
+
+
+/**
+ * \brief 判断点在凸多面体的每个面的内侧还是外侧
+ */
+int IsInsidePlane(Eigen::VectorXf testPoint, Eigen::VectorXf vertex0, Eigen::VectorXf vertex1, Eigen::VectorXf vertex2, bool& InsidePlaneElement)
+{
+    Eigen::Vector3f v = vertex1 - vertex0;
+    Eigen::Vector3f u = vertex2 - vertex0;
+    Eigen::Vector3f n = v.cross(u).normalized();
+    float dist = n.dot(testPoint) - n.dot(vertex0);
+
+    if (dist >= 0)
+        InsidePlaneElement = true;
+    else
+        InsidePlaneElement = false;
+
+    return 0;
+}
+
+
+/**
+ * \brief 判断点云中的点是否在灵活工作空间内,灵活工作空间由12个凸多面体构成
+ */
+int IsInWorkSpace(const pcl::PointXYZ &point, StructPoint3f transformedVertexPoints[13][3], bool& InWorkSpace)
+{
+    
+    // 待测试的点转换成向量
+    Eigen::VectorXf testPoint(3);
+    testPoint << point.x, point.y, point.z;
+
+    // 待测试的点是否在凸多面体内
+    bool InsidePolyhedron[12] = { false };
+
+    for (size_t i = 0; i < 12; i++) {
+
+        bool InsidePlane[5] = { false };
+
+        Eigen::VectorXf vertex00(3);
+        vertex00 << transformedVertexPoints[i][0].X, transformedVertexPoints[i][0].Y, transformedVertexPoints[i][0].Z;
+        Eigen::VectorXf vertex01(3);
+        vertex01 << transformedVertexPoints[i][1].X, transformedVertexPoints[i][1].Y, transformedVertexPoints[i][1].Z;
+        Eigen::VectorXf vertex02(3);
+        vertex02 << transformedVertexPoints[i][2].X, transformedVertexPoints[i][2].Y, transformedVertexPoints[i][2].Z;
+        Eigen::VectorXf vertex10(3);
+        vertex10 << transformedVertexPoints[i + 1][0].X, transformedVertexPoints[i + 1][0].Y, transformedVertexPoints[i + 1][0].Z;
+        Eigen::VectorXf vertex11(3);
+        vertex11 << transformedVertexPoints[i + 1][1].X, transformedVertexPoints[i + 1][1].Y, transformedVertexPoints[i + 1][1].Z;
+        Eigen::VectorXf vertex12(3);
+        vertex12 << transformedVertexPoints[i + 1][2].X, transformedVertexPoints[i + 1][2].Y, transformedVertexPoints[i + 1][2].Z;
+
+        IsInsidePlane(testPoint, vertex00, vertex01, vertex02, InsidePlane[0]);
+        IsInsidePlane(testPoint, vertex00, vertex10, vertex01, InsidePlane[1]);
+        IsInsidePlane(testPoint, vertex00, vertex02, vertex12, InsidePlane[2]);
+        IsInsidePlane(testPoint, vertex02, vertex01, vertex11, InsidePlane[3]);
+        IsInsidePlane(testPoint, vertex10, vertex12, vertex11, InsidePlane[4]);
+
+        InsidePolyhedron[i] = std::all_of(std::begin(InsidePlane), std::end(InsidePlane), [](bool val) { return val; });
+
+    }
+
+    InWorkSpace = std::any_of(std::begin(InsidePolyhedron), std::end(InsidePolyhedron), [](bool val) { return val; });
+
+    //// 假设灵活工作空间的边界是 -10 到 10
+    //if (point.x >= -10.f && point.x <= 10.f &&
+    //    point.y >= -10.f && point.y <= 10.f &&
+    //    point.z >= -10.f && point.z <= 10.f) {
+    //    InWorkSpace = true;
+    //}
+    //else {
+    //    InWorkSpace = false;
+    //}
+
+    return 0;
+}
+
+
+
+
+/**
+ * \brief 根据灵活工作空间,提取灵活工作空间内的点云
+ * \param cloudData 点云数据
+ * \param return 0
+ */
+RUS_EXECUTION_STATUS __stdcall PCLInWorkSpace(StructPCLDataInfo cloudData, StructPoint3f transformedVertexPoints[13][3], StructPCLDataInfo& cloudInWorkSpace, double& cloudRatio)
+{
+    SetLogDirectoryAndFileWorkSpace();
+
+    if (cloudData.pData == nullptr)
+    {
+        LogError("the input point cloud data is empty in the PCLInWorkSpace!\n");
+        return RUS_POINT_DATA_NULL;
+    }
+
+    try
+    {
+        // 将点云数据转换成pcl格式
+        PointPtr cloud = Convert2PCLCloud(cloudData);
+        
+        /*
+        // 提取灵活工作空间内的点云workSpacePoints
+        */
+        PointPtr workSpacePoints(new PointCloud);
+        for (const auto& point : cloud->points)
+        {
+            bool InWorkSpace = false;
+
+            IsInWorkSpace(point, transformedVertexPoints, InWorkSpace);
+
+            if (InWorkSpace == true)
+            {
+                workSpacePoints->points.push_back(point);
+            }
+        }
+        workSpacePoints->width = workSpacePoints->points.size();
+        workSpacePoints->height = 1;
+        workSpacePoints->is_dense = false;
+
+        cloudRatio = workSpacePoints->width / cloud->width;
+
+        PCLCloudConvert2CloudData(workSpacePoints, cloudInWorkSpace);
+    }
+    catch (...)
+    {
+        LogError("exception in PCLInWorkSpace while processing the point cloud!\n");
+        return RUS_FAILED_UNKNOWN;
+    }
+
+    return RUS_SUCCESSED;
+}

+ 19 - 0
SourceCode/Deprecated/RUS/SourceCode/RUSTasks/TaskPCLDataPreprocess/PCLPreprocessUtils/PCLInWorkSpace.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#ifndef __CCLOUDPATHGENERATOR_H__
+#define __CCLOUDPATHGENERATOR_H__
+#include <cstdint>
+#include <Eigen/Dense>
+#include <algorithm>
+
+#include "CommonTypes.h"
+
+#include "RusErrorCode.h"
+
+extern "C"
+{
+    // 处于灵活工作空间的点云
+    _declspec(dllexport) RUS_EXECUTION_STATUS __stdcall PCLInWorkSpace(StructPCLDataInfo cloudData, StructPoint3f transformedVertexPoints[13][3], StructPCLDataInfo& cloudInWorkSpace, double& cloudRatio);
+}
+#endif
+#pragma once