我的订单|我的收藏|我的商城|帮助中心|返回首页
虚拟现实新闻>VR>行业资讯>行业知识

机构运动仿真中的三维实体的建模与装配

文章来源:第三维度 作者: 发布时间:2012年03月23日 点击数: 字号:

    来源:第三维度
    作者:韩锐(硕士学位论文)

   《 基于SolidWorks的机构运动仿真研究》第二章

    2 三维实体的建模与装配

    早期的计算机运动仿真都是以二维图形的形式出现的,从最初的以简单的线条来模拟现实之中的各种机构,发展到后来精细化的二维图形运动仿真,都没有突破二维的界限。客观地讲,二维图形对空间复杂机构的运动仿真显得力不从心。随着计算机软硬件和计算机图形学的发展,三维实体运动仿真成为可能。三维仿真系统中的运动构件都以三维实体的形式出现,更符合人的视觉习惯和思维习惯,更能够代表显示生活中的实际情况,也使空间机构的运动仿真成为现实。

    本章阐述了SolidWorks 中进行二次开发的一般过程以及三维实体的建模和装配方法。在建模方面,指出了三维实体的两种不同建模方法,利用自定义的资源完成了实体的参数化建模。另外,还介绍了构件位姿设置的过程和方法。

    2.1 SolidWorks 及其二次开发技术简介

    2.1.1 三维造型软件SolidWorks【5】

    SolidWorks 软件是在Windows 环境下开发的三维实体设计软件,它能够充分利用Windows 的优秀界面,为设计师提供了简易方便的工作界面。SolidWorks 首创的特征管理,能够将设计过程的每一步记录下来,并形成特征管理树,显示在屏幕的左侧。设计师可以随时点取任意一个特征进行修改,还可以随意调整特征树的顺序,以改变零件的形状。由于SolidWorks 全面采用Windows 的技术,因此在零件设计时可以对零件的特征进行“剪切、复制、粘贴”等操作。SolidWorks 软件提供完整的、免费的开发工具(API),用户可以用微软的Visual Basic、Visual C++或其它支持OLE 的编程语言建立自己的应用方案。通过数据转换接口,SolidWorks 可以很容易地将目前市场几乎所有的机械CAD 软件集成到现在的设计环境中来。

    SolidWorks 是Windows 原创的三维实体设计软件,全面支持微软的OLE 技术。它支持OLE2.0 的API 后继开发工具已经改变了CAD/CAE/CAM 领域传统的集成方式,使得不同的应用软件能集成到同一个窗口,共享同一数信息,以相同的方式操作,没有文件传输的烦恼。

    SolidWorks 软件在用户界面方面的方便程度是世界公认的, 该软件自1995 年问世以来,先后共获得工业界的十几次大奖,这在同档次软件中是获奖次数最多的软件。

    2.1.2 基于SolidWorks 的二次开发技术【6】

    为了方便用户进行二次开发,SolidWorks 提供了OLE 应用程序开发接口SolidWorks API,其中包含有数以百计的功能函数,用户可以使用支持OLE 编程的开发工具,如用VB、VBA、C、VC++等都能对这些功能函数进行调用,为程序员提供了直接访问SolidWorks 的能力。通过适当的方法调用SolidWorks API,应用其中丰富的函数进行二次开发,可以建立适合用户需要的专用SolidWorks 运动仿真模块。如果采用VC6.0 作为开发工具,进行开发的步骤是:首先,从SolidWorks 公司的网站下载向导文件SWizard.awx, 将其拷贝至c: \ Microsoft VisualStudio\Common\MSDev98\Template 目录下。然后,在VC 中用该向导创建DLL 工程,加入相关代码,编译生成*.dll 文件。还有一种方法就是应用c:\Program Files\SolidWorks\samples 下的三个示例工程为基础进行开发,它们分别是testapp、userdll 和comuserdll,这些工程已经具备了基本的程序框架,程序员可以在此基础上开发自己的应用程序。一般而言,开发人员首先需要在SolidWorks 的界面上添加自己的菜单项,以此作为激活用户程序的接口,完成与用户的数据交换。在上述过程中,用户程序必须响应SolidWorks 的一些消息通知,以保证各个操作的合法性。

    SolidWorks API 提供了两种接口的方式:Dispatch 和COM。两者都可以实现OLE 自动化,但作者发现,Dispatch 接口和COM 接口生成的DLL 插件具有各自的特点:采用COM 接口生成的DLL 在Windows 注册表注册成功后,可通过选择SolidWorks“工具”菜单下的“插件”,将DLL 程序载入,下次启动SolidWorks 时,DLL 插件能够自动加载,通常情况下,只要没有在“插件”菜单项中清除DLL 插件,每次启动后都能出现插件菜单,使用下载的向导文件SWizard.awx 生成的DLL 插件就是这种类型;Dispatch 接口生成的DLL 不需要进行注册表注册,启动SolidWorks 后,在“文件”菜单下的“打开”菜单中选择需要加载的DLL程序,即可以将DLL 插件嵌入SolidWorks,Dispatch 接口生成的DLL 也可以注册,不过需要程序员自己编写注册程序,SolidWorks 自带的示例工程testapp 和userdll 生成的DLL 插件就是这种类型。本文使用了Dispatch 接口方式开发运动仿真程序。

    进行 SolidWorks 二次开发之前,还必须熟悉SolidWorks API 对象。SolidWorks API 接口采用面向对象的方法,所有的函数都是有关对象的方法或属性。SolidWorks 提供了大量的API 对象用于二次开发,这些对象涵盖了全部的SolidWorks 的数据模型,通过对这些对象属性的设置和方法的调用,就可以在用户自己开发的DLL 中实现与SolidWorks 相同的功能和操作。

    2.2 SolidWorks 插件(add-in)程序中的资源

    在普通的 VC++程序中,用户可以定义和使用自己创建的资源,包括对话框、工具条、光标、位图等,这些资源均可以在程序中自由使用。二次开发的SolidWorks 插件程序中也可以创建自己的资源,但资源的使用方法却与普通VC 程序有所不同,如果直接使用插件程序中的资源,SolidWorks 主程序通常会在显示用户资源之后停止响应,只能用强制中断的方式才能关闭SolidWorks,造成这种现象的原因是系统无法返回SolidWorks 原有的资源,从而使SolidWorks 无法使用。

    如果在插件程序中包含自定义的资源,那么这些资源在使用时必须遵循以下顺序:

    1. 获取并保存当前资源

    2. 设置用户资源为当前资源

    3. 使用用户资源

    4. 释放用户资源

    5. 重新设置以前保存的资源

    本课题使用了工具条和对话框资源,用户通过屏幕菜单可以添加工具条,再用工具条上的按钮打开对话框,完成三维模型主要参数的输入,然后根据输入的参数生成需要的三维模型。下面分别介绍如何添加工具条和对话框。

    2.2.1 SolidWorks 中的自定义工具条

    在 SolidWorks 中添加工具条需要用到LoadMappedBitmap 、AddToolbar、AddToolbarCommand、ShowToolbar 等SolidWorks API 函数,这些函数的用法可以通过查阅SolidWorks API help 得到。

    首先,在VC++工程中添加自定义工具条,SolidWorks API 函数AddToolbar 需要定义两种大小不同的工具条资源,一种为16×16 像素,另一种为32×32 像素,这两个资源分别定义为IDR_TOOLBAR_SMALL和IDR_TOOLBAR_BIG。

    然后,在程序菜单项对应的函数中添加如下代码:

    HINSTANCE CurrentResource=AfxGetResourceHandle();//获取并保存当前资源

    HINSTANCE NewInstance=LoadLibrary(_T("TestApp.dll"));//加载动态链接库“TestApp.dll”

    AfxSetResourceHandle(NewInstance); //设置应用程序使用用户资源

    m_SmallToolbar.LoadMappedBitmap(IDR_TOOLBAR_SMALL);

    HBITMAP hbmSmallImageWell= (HBITMAP)m_SmallToolbar.GetSafeHandle();

    m_LargeToolbar.LoadMappedBitmap(IDR_TOOLBAR_BIG);

    HBITMAP hbmLargeImageWell= (HBITMAP)m_LargeToolbar.GetSafeHandle();

    m_ToolbarId=m_pSolidWorks->AddToolbar(_T("TestApp"),

    _T("TestToolbar"),(long)hbmSmallImageWell,(long)hbmLargeImageWell);

    m_pSolidWorks->AddToolbarCommand(_T("TestApp"),m_ToolbarId,0,_T("ToolCB0@ToolbarUpdate0,第一个图标")); //第一个按钮对应函数ToolCB0

    m_pSolidWorks->AddToolbarCommand(_T("TestApp"),m_ToolbarId,1,_T("ToolCB1@ToolbarUpdate0,第二个图标"));//第二个按钮对应函数ToolCB1 //其他按钮

    m_pSolidWorks->ShowToolbar (_T("TestApp"), m_ToolbarId);//显示工具条FreeLibrary(NewInstance); //释放用户资源

    AfxSetResourceHandle(CurrentResource); //重置原资源以上程序严格遵循了上文提到的5 步顺序。

    最后,启动SolidWorks,加载插件程序TestApp.dll,用菜单可以加载并显示工具条,加载后的工具条如图2-1 所示:

基于SolidWorks的机构运动仿真研究(2)
图2-1 在SolidWorks 环境下添加工具条

    2.2.2 在SolidWorks 中使用自定义对话框

    在 SolidWorks 中使用自定义对话框的方法与使用工具条的方法类似,都要注意资源的使用顺序。首先在VC++工程中添加对话框资源IDD_DIALOG1,其对应的C++类为CexchangDialog,同时,在调用对话框的*.cpp 文件头添加:

    #include "ExchangDialog.h"

    然后,在菜单项或工具条项对应的函数中添加如下代码:

    HINSTANCE CurrentResource=AfxGetResourceHandle();//获取并保存当前资源

    HINSTANCE NewInstance=LoadLibrary(_T("TestApp.dll"));//加载动态链接库“TestApp.dll”

    AfxSetResourceHandle(NewInstance); //设置应用程序使用用户资源

    CExchangDialog dlg; //创建类的对象dlg

    dlg.DoModal(); //显示对话框

    FreeLibrary(NewInstance); //释放用户资源

    AfxSetResourceHandle(CurrentResource); //重置原资源

    在菜单项或工具条中调用以上程序,即可在SolidWorks 中添加自定义对话框,图2-2 所示的是设置曲柄滑块机构中曲柄和连杆长度的对话框。

图2-2 曲柄滑块机构设置对话框
图2-2 曲柄滑块机构设置对话框

    2.3 参数化建模方法

    在 SolidWorks 中参数化建模可以通过两种方法实现,一种方法是用户根据需要直接用程序生成需要的模型,称为完全程序化参数建模;另一种方法是利用已有的模型,通过修改模型参数的方法得到需要的模型,称为参数修改法建模。

    2.3.1 完全程序化参数建模

    采用程序方法进行建模时,建模的过程完全由程序进行控制,相当于将手动分步建模的过程由计算机连续完成。理论上讲,凡是手工建模能够完成的复杂模型都可以用这种方法生成。完全程序建模的方法特别适合生成具有多个变参数的模型,建模的灵活性强,不需要模型库的支持,可以在建模的同时完成设计计算、强度校核、寿命计算等工作,程序可实现的功能强大,参数的输入也可以采用数据库等多元化的方法。

    通常情况下,这种方法的程序设计工作量较大,要求程序员对SolidWorksAPI 函数具有较高的理解和运用能力,适合于模型比较简单、参数变量多或参数间有关联的情况。由于SolidWorks API 的函数较多,全部熟悉比较困难,一个简单的了解函数应用的办法是通过SolidWorks 中的宏来记录用户在造型过程中的操作,所有的操作会以VBscript 的形式保存下来,而几乎所有的VC++函数名与VBscript 的函数名相同或类似,然后通过帮助得到相应函数的用法。

    完全程序化参数建模的效率与模型的复杂程度有关,模型越复杂则建模的时间越长,编制程序的工作量越大。完全程序化建模的执行过程与手工建模的过程基本一致,较容易理解,这种方法的难点在于要求程序员对SolidWorks API 函数具有较高的理解和运用能力,而实际上要做到这一点是需要付出一定的时间和努力的。对于初学者,使用这种方法有助于更好的理解和运用SolidWorks API 函数。

    2.3.2 参数修改法建模

    参数修改法建模是通过修改现有模型的参数来实现参数化建模的方法,采用参数修改法建模必须有模型库的支持,模型库通常由用户事先用手工方式建立,保存在程序指向的目录下。需要使用时,从模型库中打开模型文件,对指定的尺寸参数进行修改、重建,就可以获得满足要求的模型。这种方法的程序设计工作量小,与造型过程无关,适用于模型标准化程度高的情况或造型过程复杂、可变参量少的情况。参数修改法建模对模型库的要求较高,手工建模时需要综合考虑尺寸标注方式,尽量避免尺寸参数间的关联和制约关系,需要修改的尺寸参数必须独立标注,尺寸标注的名称可通过查阅其属性获得。可变参数的输入可以通过对话框、数据库等多种方式实现,也可以从程序设计计算的结果中获得。修改模型参数前必须打开零件库中对应的零件,打开零件的操作可以由手动完成,也可以通过程序完成。

    这种建模方法不需要程序员掌握大量的API 建模函数,程序的复杂程度与模型的复杂程度无关。由于参数修改必须对应指定的标注对象和零件对象,所以这种建模方法对模型库的依赖性很强,模型库一旦确定就不能随意修改,否则将造成程序无法正常运行。

曲柄的长度参数
图2-4 曲柄的长度参数

基于SolidWorks的机构运动仿真研究(2)
图2-5 曲柄的草图

    如图2-4 所示的曲柄零件,杆长L 是参数化建模需要修改的参数,该曲柄零件与其他模型零件一样,保存在指定的模型库目录下,通过API函数OpenDoc4( ) 可以在程序中打开模型库中的曲柄模型文件roddg1 .SLDPRT。

    打开曲柄零件的草图,如图2-5 所示,在草图中找到杆长参数L,其数值为150mm,是独立标注的长度参数,选中并查看其属性可得到该标注对象的名称为:“D14@草图1”,该对象就是程序的目标对象。参数化建模时,在程序中要首先找到该标注对象,然后调用相应的API 函数对其重新进行设置就可以改变模型的参数。最后重建模型、刷新屏幕,就可以得到需要的模型。下面程序将修改杆长参数,将其设置为50mm。

    LPDISPATCH retval=UserApp->getSWApp()->ActivateDoc(_T("roddg1"));//找到杆件对象

    LPDISPATCH modDisp =UserApp->getSWApp()->GetActiveDoc();

    IModelDoc m_pMod(modDisp); //获得IModelDoc 对象m_pMod

    IPartDoc part1(modDisp); //获得IPartDoc 对象part1

    LPDISPATCH pDim=m_pMod.Parameter("D14@草图1"); //找到标注对象

    IDimension Dime(pDim); //获得IDimension 对象Dime

    Dime.SetValue(RodLength/1000); //设置D14 的值为RodLength =50

    part1.EditRebuild(); //零件重建

    m_pMod.WindowRedraw(); //屏幕刷新

    程序中“roddg1”为模型库中曲柄零件的文件名,"D14@草图1" 为标注对象的名称, Rlength 变量来自对话框的输入,由于SetValue()函数使用的长度单位是m,所以Rlength 还要除以1000 转化为m。由图2-6 可以看到,曲柄长度有了明显变化。

曲柄长度参数变化前后对比图          基于SolidWorks的机构运动仿真研究(2)
(a) 曲柄长度L=150mm              (b) 曲柄长度L=50mm
图2-6 曲柄长度参数变化前后对比图

    程序中“roddg1”为模型库中曲柄零件的文件名,"D14@草图1" 为标注对象的名称, Rlength 变量来自对话框的输入,由于SetValue()函数使用的长度单位是m,所以Rlength 还要除以1000 转化为m。由图2-6 可以看到,曲柄长度有了明显变化。

    通过以上的方法,本文建成了运动仿真用的模型库,其中的主要零件如表2-1 所示。

    表2-1 模型库主要零件示意图基于SolidWorks的机构运动仿真研究(2)

    2.4 三维实体零件的装配

    2.4.1 坐标系与位姿矩阵的变换

    如图 2-7 所示,在SolidWorks 中,对于每一个装配体,系统会提供一个整体坐标系xyz ;对于装配体中的每一个零件来说,又有一个局部坐标系x′y′z′(又称零件坐标系),整体坐标系只有一个,局部坐标系可以有多个。为了保持坐标的统一,整体坐标系在程序中一般很少进行变换,而零件坐标系正好相反。为了实现装配或运动仿真,零件在装配体中必然要进行平移,旋转等操作,这就要对零件坐标系进行变换。

图2-7 整体坐标与局部坐标
图2-7 整体坐标与局部坐标

    装配体中零件的位姿(包括零件的位置坐标和沿三个坐标轴的旋转)是由一个4×4位姿矩阵规定的,该矩阵表示了整体坐标系与局部坐标系的相对关系。

    运动仿真中零件的平移,旋转等操作都是通过设置位姿矩阵实现的,设置位姿矩阵的过程即坐标变换的过程。在本课题中,主要用到了三维平移变换和绕坐标轴的三维旋转变换。

    a. 三维平移变换

    一个三维空间点P(x, y, z)平移( , , ) x y z T T T T 后到达P′(x′, y′, z′),其平移变换方程为

     基于SolidWorks的机构运动仿真研究(2)                               (2-1)

     基于SolidWorks的机构运动仿真研究(2)              (2-2)

    即P′ = T ⋅ P                             (2-3)

     式(2-3)中

         基于SolidWorks的机构运动仿真研究(2)                   (2-4)

    T 为三维平移变换矩阵。

    b. 绕坐标轴的三维旋转变换

    在三维旋转中,旋转角θ 是这样规定的:从坐标轴正向朝坐标原点看去,逆时针旋转时θ 为正值,顺时针旋转时为θ 为负值。与式(2-3)类似,三维旋转变换有

    P′ = R- P                         (2-5)

    根据绕坐标轴的不同,变换矩阵 R 有如下三种形式:

    (1) 绕 z 轴旋转变换:三维实体绕z 轴旋转θ 时,所有点的z坐标不变,x、y 坐标发生变化,其变换矩阵为

        基于SolidWorks的机构运动仿真研究(2)                           (2-6)

    (2) 绕 y 轴旋转变换:三维实体绕y 轴旋转θ 时,所有点的y坐标不变,x、z 坐标发生变化,其变换矩阵为

    基于SolidWorks的机构运动仿真研究(2)                                   (2-7)

    (3) 绕 z 轴旋转变换: 三维实体绕z 轴旋转θ 时,所有点的z坐标不变,x、y 坐标发生变化,其变换矩阵为

       基于SolidWorks的机构运动仿真研究(2)                                  (2-8)

    2.4.2 向装配体中添加实体零件

    SolidWorks 向装配体中添加零件有两种方法:手动方法和程序方法。手动方法的自动化程度很低,不适合在本课题中应用;用程序方法添加零件时,必须首先打开要添加的零件文件,然后才能用API 函数添加到装配体的指定位置。

    在 SolidWorks API 中,打开零件文件是通过OpenDoc4()函数实现的,向装配体中添加零部件是通过assemblyDoc 对象的AddComponent2()函数实现的,AddComponent2()函数的具体使用方法如下:

    LPDISPATCH modDisp =UserApp->getSWApp()->GetActiveDoc();

    IAssemblyDoc assembly(modDisp);

    assembly.AddComponent2("c:\\sw\\roddg1.SLDPRT",x,y,z);

    AddComponent2()函数只能指定加入零件的原点在整体坐标系中的位置坐标,即只能指定零件原点相对于整体坐标的位移x、y、z,不能指定零件的旋转。对于大多数的应用场合,仅使用AddComponent2()函数是不能完成零件的最终装配的,要完全完成零件的装配,还要对装配体中零件的位姿进行设置。

    2.4.3 零件的位姿设置

    上文已经提到,零件的局部坐标系和整体坐标系之间的相对关系由一个的4×4 位姿矩阵规定,矩阵中的元素值为0 2 P , P ⋯ 15 P , 通过SolidWorks API 中Component 对象的GetXform()函数可返回位姿矩阵中的元素值。各元素值在矩阵中的位置与数学中的有所不同,其位置为:

    基于SolidWorks的机构运动仿真研究(2)                     (2-9)

    即如需指定零件的 X 位置,需将9 P 元素设置为指定的X 值,矩阵形式为

     基于SolidWorks的机构运动仿真研究(2)                   (2-10)

    零件绕z 轴旋转ϕ 角的矩阵形式为

    基于SolidWorks的机构运动仿真研究(2)            (2-11)

    位姿设置的过程如图2-8 所示,每个装配体都有唯一的一个根构件,根构件通常是第一个添加到装配体中的零件。

基于SolidWorks的机构运动仿真研究(2)
图2-8 位姿设置流程图

    在根构件后面添加到装配体中的零件作为根构件的子构件,可以从根构件开始,逐一遍历所有子构件,在遍历过程中,不断提取当前构件的构件名,当提取的构件名与需要改变位姿的零件名相符时,即可调用相应的API 函数对其位姿进行设置,具体方法是:调用ModelDoc 对象的GetActiveConfiguration()函数和Configuration 对象的GetRootComponent()函数可获得装配体的根构件RootComponent , RootComponent 为Component 对象,再调用Component 对象的 GetChildren()函数及相应的转换可以获得装配体中的构件总数nChild。以nChild 为判断条件循环遍历装配体中的所有零件,Component 对象的GetName()函数可以获得当前构件的装配名称,当获得的构件名与需要旋转的零件名一致时,构造一个4×4位姿矩阵,矩阵中存储了改变后的构件位姿,调用Component对象的SetXform()函数,用新的位姿矩阵替换原有的位姿矩阵,刷新屏幕后即可改变指定零件的位姿。通过“遍历─设置”这一过程,就可对装配构件的初始位姿进行设置。

    位姿设置的总体思路都是首先通过遍历的方法选中需要改变位姿的构件,再用构造的新矩阵替换原有矩阵。选中构件的方法有很多种,可以通过构件名的方法,也可以通过构件的其他特征进行选择。

    2.5 构件的运动控制

    构件的运动控制就是控制构件以一定运动规律在屏幕上运动,运动控制与装配中的位姿设置有一些区别,也有一定联系。两者的区别在于:

    装配时,每个构件只需要设置一次位姿;而运动控制需要按照一定的时间间隔连续的设置构件的位姿,当时间间隔足够小的时候,用户在屏幕上看到的就是连续运动的构件。两者的联系在于:设置位姿的过程都是按照图2-8 所示的流程进行的。

    通过对计时器及相关标志位的控制,可以实现构件运动的正反转、暂停和停止。首先声明一个回调函数waitdoall,该函数由计时器触发,每隔一定的时间间隔调用一次。函数声明如下:

    void CALLBACK waitdoall( HWND hwnd, UINT uMsg, UINT idEvent,DWORD dwTime );

    设置计时器的函数如下:

    timerall=SetTimer(NULL,1,30,(TIMERPROC)waitdoall);

    waitdoall 函数的代码如下:

    void CALLBACK waitdoall( HWND hwnd, UINT uMsg, UINT idEvent,DWORD dwTime )

    {if(judge%2==0) //判断是否暂停

    {……} //判断方向,设置构件位姿}

    其中出现的int 型变量judge,点击暂停按钮会调用以下函数改变judge的值,实现运动的暂停和继续。

    void CPartList::rotpause()

    { judge=judge+1;

    }

    要停止构件运动,只需要关闭计时器,点击停止按钮调用如下函数关闭计时器。

    void CPartList::rotstop()

    { killtime=KillTimer(NULL,timerall);
    judge=0;
    }

  • 暂无资料
  • 暂无资料
  • 暂无资料
  • 暂无资料
  • 暂无资料