Solidworks API利用C# 实现物体的运动与碰撞检测

news2024/9/22 19:22:57

详情见github连接

SolidWorks-API-Collision-Detection

Use SolidWorks API to MovePart and Collision Detection 利用solidworks的API来移动控件物体以及进行碰撞检测

visual studio 2022 利用Nuget 安装这些库

在这里插入图片描述

打开solidworks

可以看到有两个控件

部件运动

使用封装的函数void MovePart(string partName,double thetax,double thetay,double thetaz, double xDistance, double yDistance, double zDistance,double scale)改变部件partname 是部件名称 比如 床 在这里插入图片描述

他的部件名应该为string partName = “bed2-1”; 您可以参考样例来学习更多的使用;
thetax、thetay、thetaz分别是让物块按照不同的轴转动,您也可以三个都写进行复杂转动,该函数中已经将多角度转动融合了。注意,这里的转动是转动到指定位置,而不是转动多少度。比如你想要30°,60°,您应该直接写对应的角度,而不是运行两次30°。
xDistance、yDistance、zDistance分别是指定轴方向的平移,这个平移经不确定的测量,可能1代表1m的运动距离 这个就是实打实的运动1m,比如你要0,1,2,3m的位置距离,那就多次写入运行1
scale是放缩该部件,这里不做赘述。

连接solidworks

打开solidworks后 连接solidworks 这里我写了一个简单的界面的连接按钮。

在这里插入图片描述

连接成功

在这里插入图片描述

即可对物块进行操作了,例如 旋转30°

在这里插入图片描述

进行碰撞检测

bool CheckForInterference() 调用后如果当前所有界面中有碰撞 那么会返回true 否则返回false

组合运用部件运动和碰撞检测

组合运动上述两个功能,即可用solidworks模拟机械设备运动,并知晓当前位置是否会发生碰撞,最终知道在各个位置是否会出现碰撞冲突,存入数据库,以指导机械运动的安全联锁。

粗略代码,详见github

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SolidWorks.Interop.swdocumentmgr;
using SolidWorks.Interop.sldworks;
using System.Diagnostics;
using System.Runtime.InteropServices;
using SolidWorks.Interop.swconst;
using System.Threading;
using System.Threading.Tasks;
using System.Collections;
using System.Data;
using System.Data.SqlClient;


namespace TEST2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private static SldWorks SwApp;
        private static AssemblyDoc swAssembly;
        private static ModelDoc2 swModel;


        public static ISldWorks ConnectToSolidWorks()
        {
            if (SwApp != null)
            {
                return SwApp;
            }
            else
            {
                Debug.Print("connect to solidworks on " + DateTime.Now);
                try
                {
                    SwApp = (SldWorks)Marshal.GetActiveObject("SldWorks.Application");
                }
                catch (COMException)
                {
                    try
                    {
                        SwApp = (SldWorks)Marshal.GetActiveObject("SldWorks.Application.23"); // 2015
                    }
                    catch (COMException)
                    {
                        try
                        {
                            SwApp = (SldWorks)Marshal.GetActiveObject("SldWorks.Application.26"); // 2018
                        }
                        catch (COMException)
                        {
                            MessageBox.Show("Could not connect to SolidWorks.", "SolidWorks", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                            SwApp = null;
                        }
                    }
                }

                return SwApp;
            }
        }

       



        //运动单位为m 因此1mm挪动应该为0.01
        // thetax 是角度 绕某个轴旋转  Distance是位移 绕某个轴平移 scale是放缩
        private void MovePart(string partName,double thetax,double thetay,double thetaz, double xDistance, double yDistance, double zDistance,double scale)
        {
            if (swAssembly == null)
            {
                MessageBox.Show("swAssembly is null");
                return;
            }

            // 获取部件
            Component2 swComponent = swAssembly.GetComponentByName(partName);
            if (swComponent != null)
            {
                // 获取IMathUtility对象
                IMathUtility mathUtil = (IMathUtility)SwApp.GetMathUtility();

                // 获取当前变换矩阵
                IMathTransform componentTransform = swComponent.Transform2;

                if (componentTransform == null)
                {
                    MessageBox.Show("Component Transform is null");
                    return;
                }

                // 获取当前变换矩阵的数据
                double[] transformData = (double[])componentTransform.ArrayData;
                // 修改平移部分的值
                // X轴旋转
                double cosThetax = Math.Cos(thetax/ 57.295779513);
                double sinThetax = Math.Sin(thetax/ 57.295779513);
                double cosThetay = Math.Cos(thetay / 57.295779513);
                double sinThetay = Math.Sin(thetay / 57.295779513);
                double cosThetaz = Math.Cos(thetaz / 57.295779513);
                double sinThetaz = Math.Sin(thetaz / 57.295779513);

                double[,] matrixx = new double[,]
                {
                    {1, 0, 0},
                    {0, cosThetax, -sinThetax},
                    {0, sinThetax, cosThetax}
                };

                double[,] matrixy = new double[,]
                {
                    {cosThetay, 0, sinThetay},
                    {0, 1, 0},
                    {-sinThetay, 0, cosThetay}
                };

                double[,] matrixz = new double[,]
                {
                    {cosThetaz, -sinThetaz, 0},
                    {sinThetaz, cosThetaz, 0},
                    {0, 0, 1}
                };


                double[,] intermediateResult = MultiplyMatrices(matrixx, matrixy);
                double[,] finalResult = MultiplyMatrices(intermediateResult, matrixz);
                int index = 0;
                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        transformData[index] = finalResult[i, j];
                        index++;
                    }
                }
                transformData[9] += xDistance; // X轴平移
                transformData[10] += yDistance; // Y轴平移
                transformData[11] += zDistance; // Z轴平移
                transformData[12] = scale;
                // 创建新的变换矩阵并设置修改后的数据
                IMathTransform newTransform = (IMathTransform)mathUtil.CreateTransform(transformData);

                // 将新的变换矩阵应用到部件上
                swComponent.Transform2 = (MathTransform)newTransform;

                swModel.GraphicsRedraw2();
            }
            else
            {
                MessageBox.Show("未找到部件: " + partName);
            }
        }





        private void ListComponents()
        {
            if (swAssembly == null)
            {
                MessageBox.Show("swAssembly is null");
                return;
            }

            int componentCount = swAssembly.GetComponentCount(false);
            object[] components = (object[])swAssembly.GetComponents(false);

            StringBuilder componentNames = new StringBuilder();
            foreach (Component2 component in components)
            {
                componentNames.AppendLine(component.Name2);
            }

            MessageBox.Show(componentNames.ToString(), "Component Names");
        }


        private async void RotatePartContinuously(string partName, double thetax, double thetay, double thetaz, double xDistance, double yDistance, double zDistance, double scale, int intervalMs)
        {

            for(int j =0; j < 360;j = j+ 5)
            {
                MovePart(partName, j, 0, 0, xDistance, yDistance, zDistance, scale);
                await Task.Delay(100);
                if (CheckForInterference())
                {
                    Console.WriteLine("yes");

                }
                else
                    Console.WriteLine("no");
            }
        }
        static double[,] MultiplyMatrices(double[,] matrix1, double[,] matrix2)
        {
            double[,] result = new double[3, 3];

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    for (int k = 0; k < 3; k++)
                    {
                        result[i, j] += matrix1[i, k] * matrix2[k, j];
                    }
                }
            }

            return result;
        }
        //test
        private void MoveBed_button_Click(object sender, EventArgs e)
        {
            // 尝试移动部件
            string partName = "bed2-1"; // 确保这是装配体中实际存在的部件名称
            string partName1 = "gantry-1";
            double theta = 5; // 每次旋转的角度
            int axis = 1; // 旋转轴
            double xDistance = 0; // X 轴平移
            double yDistance = 0; // Y 轴平移
            double zDistance = 0; // Z 轴平移
            double scale = 1; // 缩放因子
            int intervalMs = 1000; // 每次旋转的时间间隔(毫秒)
            MovePart(partName1, 0, 0, 30, xDistance, yDistance, zDistance, scale);

            // RotatePartContinuously(partName, 0,0,0, xDistance, yDistance, zDistance, scale, intervalMs);
        }
        //碰撞检测
        public bool CheckForInterference()
        {
            ModelDoc2 swModelDoc = (ModelDoc2)SwApp.ActiveDoc;
            if (swModelDoc == null)
            {
                Console.WriteLine("请打开一个装配体文档.");
                return false;
            }

            AssemblyDoc swAssemblyDoc = (AssemblyDoc)swModelDoc;
            InterferenceDetectionMgr pIntMgr = swAssemblyDoc.InterferenceDetectionManager;

            // 设置干扰检测选项
            pIntMgr.TreatCoincidenceAsInterference = false;
            pIntMgr.TreatSubAssembliesAsComponents = true;
            pIntMgr.IncludeMultibodyPartInterferences = true;
            pIntMgr.MakeInterferingPartsTransparent = false;
            pIntMgr.CreateFastenersFolder = true;
            pIntMgr.IgnoreHiddenBodies = true;
            pIntMgr.ShowIgnoredInterferences = false;
            pIntMgr.UseTransform = true;

            // 设置非干扰部件的显示方式
            pIntMgr.NonInterferingComponentDisplay = (int)swNonInterferingComponentDisplay_e.swNonInterferingComponentDisplay_Wireframe;

            // 运行干扰检测
            object[] vInts = (object[])pIntMgr.GetInterferences();
            int interferenceCount = pIntMgr.GetInterferenceCount();

            // 停止干扰检测
            pIntMgr.Done();

            // 如果干扰数量大于0,则返回true,否则返回false
            return interferenceCount > 0;
        }


        private void Connect_button_Click(object sender, EventArgs e)
        {
            ISldWorks swApp = Form1.ConnectToSolidWorks();

            if (swApp != null)
            {
                string msg = "This message from C#. SolidWorks version is " + swApp.RevisionNumber();

                swApp.SendMsgToUser(msg);
                // 获取当前活动的模型文档
                swModel = (ModelDoc2)swApp.ActiveDoc;

                if (swModel == null)
                {
                    MessageBox.Show("No active document found.");
                    return;
                }

                // 检查当前文档是否为装配体
                if (swModel.GetType() == (int)swDocumentTypes_e.swDocASSEMBLY)
                {
                    swAssembly = (AssemblyDoc)swModel;
                }
                else
                {
                    MessageBox.Show("The active document is not an assembly.");
                    return;
                }
            }
            else
            {
                Console.WriteLine("Failed to connect to SolidWorks.");
            }
        }
    }

    class DatabaseHelper : IDisposable
    {
        private string connectionString;
        private SqlConnection connection;

        // 构造函数,初始化连接字符串并打开连接
        public DatabaseHelper(string serverName, string databaseName, string username, string password)
        {
            connectionString = $"Server={serverName};Database={databaseName};User Id={username};Password={password};";
            connection = new SqlConnection(connectionString);
            connection.Open();
            Console.WriteLine("数据库连接成功。");
        }

        // 插入数据的函数,传入八个参数
        public void InsertData(float gantry, float rx, float ry, float rz, float x, float y, float z, bool crash)
        {
            string insertQuery = "INSERT INTO TSS_1 (Gantry, Rx, Ry, Rz, X, Y, Z, Crash) VALUES (@Gantry, @Rx, @Ry, @Rz, @X, @Y, @Z, @Crash)";

            using (SqlCommand command = new SqlCommand(insertQuery, connection))
            {
                command.Parameters.AddWithValue("@Gantry", gantry);
                command.Parameters.AddWithValue("@Rx", rx);
                command.Parameters.AddWithValue("@Ry", ry);
                command.Parameters.AddWithValue("@Rz", rz);
                command.Parameters.AddWithValue("@X", x);
                command.Parameters.AddWithValue("@Y", y);
                command.Parameters.AddWithValue("@Z", z);
                command.Parameters.AddWithValue("@Crash", crash);

                int rowsAffected = command.ExecuteNonQuery();
                Console.WriteLine($"{rowsAffected} 行插入成功。");
            }
        }

        // 释放资源
        public void Dispose()
        {
            if (connection != null)
            {
                connection.Close();
                connection.Dispose();
                Console.WriteLine("数据库连接已关闭。");
            }
        }
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1990124.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嵌入式初学-C语言-十七

#接嵌入式初学-C语言-十六# 函数的递归调用 含义&#xff1a; 在一个函数中直接或者间接调用了函数本身&#xff0c;称之为函数的递归调用 // 直接调用a()->a(); // 间接调用a()->b()->a();a()->b()->..->a();递归调用的本质&#xff1a; 本是是一种循环…

深入理解Spring的三级缓存机制

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

Ubuntu(20.04 LTS)更换镜像源

此换镜像源方法只适用x86_64架构的系统&#xff0c;其他架构的系统参考ubuntu-ports的方法 1、备份文件 sudo mv /etc/apt/sources.list /etc/apt/sources.list.bk2、创建新文件 sudo vi /etc/apt/sources.list根据自己系统版本选择下面对应的镜像源添加到新文件中&#xf…

智能指针--

智能指针简介 头文件&分类 智能指针都在memory中&#xff0c; 有auto_ptr, unique_ptr, shared_ptr, weak_ptr 智能指针发展史 C&#xff0b;&#xff0b;98就有智能指针了&#xff08;auto_ptr&#xff09; c&#xff0b;&#xff0b;11前&#xff0c;智能指针主要靠bo…

FPGA开发——在Quartus中实现对IP核的PLL调用

一、简介 PLL主要由鉴相器&#xff08;PD&#xff09;、环路滤波器&#xff08;LF&#xff09;和压控振荡器&#xff08;VCO&#xff09;三部分组成。鉴相器检测输入信号与VCO输出信号的相位差&#xff0c;并输出一个与相位差成正比的电压信号。该信号经过环路滤波器滤除高频噪…

esp32学习笔记

前言&#xff1a;学习视频链接放在最后&#xff0c;开发方式为esp32Arduino&#xff0c;使用型号为ESP32-WROOM-32&#xff0c;引脚功能分配图如下。 #esp32介绍 GPIO的引脚默认情况下&#xff0c;只能当做普通功能引脚使用&#xff0c;也就是只能输入&#xff0c;输出&#x…

git 常用指令(创建分支、提交分支、解决冲突)

1. 初始化git 将你的代码放入你创建的文件中&#xff0c;执行 git init(前提你电脑安装过git哈)2. 查看当前项目git 状态 git status 3. 将代码添加到暂存区 git add . &#xff08;提交所有修改的代码&#xff0c;如果向指定提交使用&#xff1a;git add <文件名>&am…

SQL语句创建数据库(增删查改)

SQL语句 一.数据库的基础1.1 什么是数据库1.2 基本使用1.2.1 连接服务器1.2.2 使用案例 1.2 SQL分类 二.库的操作2.1 创建数据库2.2 创建数据库示例2.3 字符集和校验规则2.3.1 查看系统默认字符集以及校验规则2.3.2查看数据库支持的字符集2.3.3查看数据库支持的字符集校验规则2…

【RTOS面试题】ISR中可以使用互斥锁和信号量吗?

在中断服务程序&#xff08;ISR, Interrupt Service Routine&#xff09;中直接使用互斥锁&#xff08;mutex&#xff09;和信号量&#xff08;semaphore&#xff09;是有风险的&#xff0c;因为这些同步机制通常不是中断安全的。但是&#xff0c;可以通过一些方法来安全地在 I…

QWT+Qt Creator+MSVC的配置与使用

目录 一、介绍 二、QWT下载 三、QWT编译 3.1 设置构建套件 3.2 修改QWT相关文件 3.3 进行QWT编译 四、QWT配置 4.1 配置QWT的lib文件 4.2 配置QWT的dll文件 4.3 配置QWT的designer的dll文件 五、代码实验 一、介绍 QWT&#xff0c;全称是Qt Widgets for Technical…

Python 异步编程:Asyncio 实现原理

常见的并发模型 多进程/多线程异步ActorPub/Sub Python 异步的基石&#xff1a;协程 协程简介 概念&#xff1a;协作式多任务的子程序&#xff0c;用户态线程或微线程&#xff08;Coroutine&#xff09;。 特点&#xff1a;子程序执行可以中断&#xff0c;恢复后不会丢失之…

uniapp 荣耀手机 没有检测到设备 运行到Android手机 真机运行

背景&#xff1a; 使用uniapp框架搭建的项目&#xff0c;开发的时候在浏览器运行&#xff0c;因为项目要打包成App&#xff0c;所以需要真机联调&#xff0c;需要运行到Android手机&#xff0c;在手机上查看/运行项目。通过真机调试才能确保软件开发的准确性和页面显示的完整性…

mac 2k显示器 配置

前言 今年5月份买了一个2k显示器&#xff0c;刚收到的时候发现只有一个1080 x 720&#xff08;HiDPI&#xff09;分辨率是人眼看起来比较舒服的&#xff0c;于是一直用着。但是直到开始写前端代码的时候&#xff0c;我才发现&#xff0c;网页在2k显示器和内建显示器的布局竟然…

Python 循环引用与内存泄漏:深度解析

Python 循环引用与内存泄漏&#xff1a;深度解析 在Python编程中&#xff0c;循环引用和内存泄漏是两个需要特别注意的问题。本文将深入探讨Python中的循环引用现象、其导致的内存泄漏问题&#xff0c;并提供详细的解决思路与方法。同时&#xff0c;我们还将分析一些常见场景&…

【CSDN平台BUG】markdown图片链接格式被手机端编辑器自动破坏(8.6 已修复)

文章目录 bug以及解决方法bug原理锐评后续 bug以及解决方法 现在是2024年8月&#xff0c;我打开csdn手机编辑器打算修改一下2023年12月的一篇文章&#xff0c;结果一进入编辑器&#xff0c;源码就变成了下面这个样子&#xff0c;我起初不以为意&#xff0c;就点击了发布&#…

【IoT NTN】面向 5G/6G 卫星:NTN 标准发展、关键技术与未来思考

目录 国际标准化进展 架构及关键技术 5GNTN组网架构 关键技术 1、时频同步技术 2、覆盖增强技术 3、移动性管理技术 4、混合自动重传请求技术 5、自适应调制与编码技术 挑战与潜在解决方案 星地协同全域覆盖模型 星地协同多维资源调度 星地协同多层卫星路由 星地…

网络主播进入国家职业分类!1500万主播将有新身份

在营销策划界摸爬滚打十多年的我&#xff0c;最近可是被一则劲爆消息给震撼到了——国家正式官宣了19个全新职业&#xff0c;这可是职场版图的一次大扩张啊&#xff01; 其中最让人眼前一亮的是&#xff0c;网络主播竟然堂而皇之地登上了新职业的大舞台&#xff0c;正式“转正…

【多线程-从零开始-陆】wait、notify和notifyAll

线程饿死 一个或多个线程因为无法获得执行所需的资源&#xff08;如CPU时间、锁、或其他同步控制&#xff09;而被长时间阻塞或延迟执行的情况。尽管这些线程可能处于可执行状态并且已经准备好运行&#xff0c;但由于资源分配的不均衡或调度策略的问题&#xff0c;它们无法获得…

快讯 | 单卡4090显卡即可解锁视频生成,智谱AI CogVideoX模型开源!

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

认识RAID磁盘阵列

文章目录 1、RAID磁盘阵列介绍2、多种RAID级别RAID 0 &#xff08;条带化存储&#xff09;RAID 1 &#xff08;镜像存储&#xff09;RAID 5RAID 6RAID 10&#xff08;先做镜象&#xff0c;再做条带&#xff09;RAID 01&#xff08;先做条带&#xff0c;再做镜象&#xff09;区别…