首页 / 一种基于面向对象的吊装工艺流程仿真建模方法

一种基于面向对象的吊装工艺流程仿真建模方法有效专利 发明

技术领域

[0001] 本发明涉及工艺流程仿真的技术领域,具体涉及一种基于面向对象的吊装 工艺流程仿真建模方法。

相关背景技术

[0002] 工艺流程仿真在于发现问题并优化流程,通常先按照预定工艺方案进行 三维仿真演练,接下来,要么针对预定方案的不足进行修改,要么产生新的 想法设计出新的方案,最后通过多方案对比分析确定最佳方案。不难看出, 在整个过程中能否快速完成多种工艺方案的仿真演练,是决定工艺流程仿真 能否发挥作用的关键。
[0003] 现有工艺流程仿真方法主要基于数据驱动,其主要弊端在于,仿真程序 中某些关键步骤的数据变动很可能造成其它步骤的连锁反应,导致整个程序 需要重写。为提高程序的稳定性、可重用性和灵活性,采用基于面向对象的 工艺流程仿真建模技术。

具体实施方式

[0013] 下面举实施例,对本发明进行详细描述。
[0014] 本发明提供了一种基于面向对象的吊装工艺流程仿真建模方法,首先构建 通用仿真类,提供公共函数;其次通过继承仿真类构建行车类、吊车类、吊绳 类和吊钩类,提供实现各自吊装运动的专有函数;通过继承仿真类构建吊装类, 提供驱动行车类、吊车类、吊绳类和吊钩类对象、协同实现吊装工艺流程的专 有函数。
[0015] 为了能够在虚拟场景中对各类仿真对象进行运动控制,首先需要在程序中 建立各类仿真对象与要操作的仿真模型之间的映射。映射的方式是利用OSG (OpenSceneGraph)提供的变换矩阵MatrixTransform类型的指针指向需要映 射的仿真模型。当对仿真模型的根节点映射时,可以实现对仿真模型整体的操 作,如移动、旋转等,但这并不总是所希望的。因为建模往往是对于一个整体 模型而言的,而实际操作时并非是驱动模型整体,所以在映射时可能是以针对 模型的某个子模型的。例如,在建模时往往将一个行车进行整体建模,而吊车 模型则可能作为中间节点的形式出现,其下还会有吊钩子模型。而在运动时, 可能希望进行吊车移动操作。这就需要在系统中创建一个吊车对象与吊车模型 进行映射。完成了映射之后,就可以在程序中直接通过驱动吊车对象而完成吊 车模型运动了。
[0016] 仿真对象为model,仿真模型为object,变换矩阵指针为trans,对于某一 个对象来说,将仿真模型和变换矩阵指针映射给仿真对象model;对于不同的仿 真对象来说,具有从属关系的仿真对象之间、仿真模型之间、变换矩阵指针之 间分别进行映射。
[0017] 不同仿真对象构建列表反映从属关系;不同仿真模型构建场景树、父子节 点反映从属关系;变换矩阵指针决定仿真模型位置;仿真对象通过所构建函数 进行操作,利用变换矩阵指针驱动仿真模型完成相应运动。
[0018] 仿真建模方法具体如下:
[0019] 一、构建仿真类,SimuModel。提供公共函数,包括计算空间位置关系函数、 创建树形层级关系函数;计算空间位置关系函数包括设置世界坐标位移向量函 数、设置局部坐标位移向量函数、获得局部坐标位移向量函数、获得世界坐标 位移向量函数、设置欧拉角函数、设置姿态函数;创建树形层级关系函数包括 添加子仿真对象函数、添加父仿真对象函数、获得子仿真对象函数、获得父仿 真对象函数、获得所有兄弟仿真对象函数、移除仿真对象对应的场景节点函数、 移除子仿真对象函数、删除所有子仿真对象函数、移除所有父仿真对象函数。 各函数具体为:
[0020] 1-1:添加子仿真对象函数,@model子仿真对象,@addSceneNode是否在 场景树中加入节点,void addChild(SimuModel*model,bool addSceneNode), 即输入量为子仿真对象、是否在场景树中加入节点,输出量为布尔变量值,返 回0为失败,返回1为执行成功;计算过程为:(1)在当前仿真对象this维护 的子仿真对象列表m_pChildren中添加子仿真对象model,子仿真对象model 将this作为父仿真对象进行添加;(2)如果addSceneNode为真,获取model 子仿真对象对应的模型m_pObject以及变换矩阵指针m_pMatTrans,分别与该仿 真对象this的m_pObject和变换矩阵指针m_pMatTrans建立父子关系。
[0021] 1-2:添加父仿真对象函数,@model父仿真对象,@addSceneNode是否添 加场景节点标识,void addParent(SimuModel*model,bool addSceneNode), 即输入量为父仿真对象、是否添加场景节点标识,输出量为布尔变量值,返回0 为失败,返回1为执行成功;计算过程为:(1)在该仿真对象this维护的父仿 真对象列表m_pParents中添加父仿真对象model,model将该仿真对象this作 为子仿真对象进行添加;(2)如果addSceneNode为真,获取model对应的 m_pObject以及m_pMatTrans,分别与this的m_pObject和m_pMatTrans建立 父子关系。
[0022] 1-3:获得子仿真对象函数,@name子仿真对象名称,SimuModel* getChild(const string&name),即输入量为子仿真对象名称,输出量为子仿 真对象;计算过程为:遍历子仿真对象列表m_pChildren,返回具有子仿真对象 名称name的子仿真对象。
[0023] 1-4:获得父仿真对象函数,@name父仿真对象名称,SimuModel* getChild(const string&name),即输入量为子仿真对象名称,输出量为父仿 真对象;计算过程为:遍历父仿真对象列表m_pParents,返回具有name名称的 父仿真对象。
[0024] 1-5:获得所有兄弟仿真对象函数,@ret兄弟仿真对象列表,void getSiblingModels(vector&ret),即输入量为兄弟仿真对象列 表,无输出量;计算过程为:遍历父仿真对象列表m_pParents,将每个父仿真 对象的子仿真对象除本对象外压入到兄弟仿真对象列表ret中。
[0025] 1-6:移除仿真对象对应的场景节点函数,@modelToRemove要删除的 SimuModel,@mode访问器访问方式:osg::Node Visitor::TRAVERSE_ALL_ CHILDREN|osg::NodeVisitor::TRAVERSE_ALL_PARENTbool,void removeScene Node(SimuModel*modelToRemove,osg::NodeVisitor::TraversalMode mode), 即输入量为要删除的仿真对象、访问器访问方式,无输出量;计算过程为:(1) 如果mode为访问所有子仿真对象osg::
NodeVisitor::TRAVERSE _ALL_CHILDREN,则遍历m_pMatTrans所有的子节点,找到并删除modelToRemove 对应的节点;(2)如果mode为访问所有父仿真对象 osg::NodeVisitor::
TRAVERSE_PARENTS,遍历m_pMatTrans所有的父节点,找 到modelToRemove对应的节点,在该节点中删除m_pMatTrans对应的节点。
[0026] 1-7:移除子仿真对象函数,@name子仿真对象名称,@model子仿真对象, @removeSceneNode是否一并删除场景中节点,bool removeChild(SimuModel* model,bool removeSceneNode),bool removeChild(const string&name,bool removeSceneNode),即输入量为子仿真对象名称、子仿真对象、是否一并删除 场景中节点,输出量为布尔变量值,返回0为失败,返回1为执行成功;计算 过程为:(1)根据model或name遍历m_pChildren列表找到并删除子仿真对象, 同时,在子仿真对象的m_pParents列表中找到并删除当前仿真对象this;(2) 如果removeSceneNode为真,则调用removeSceneNode()函数删除子仿真对象 对应的场景节点。
[0027] 1-8:删除所有子仿真对象函数,@removeSceneNode是否移除场景节点标 识,bool removeChildren(bool removeSceneNode),即输入量为是否移除场 景节点标识,输出量为布尔变量值;计算过程为:(1)遍历m_pChildren列表 并删除所有子仿真对象;(2)如果removeSceneNode为真,则调用removeSceneNode()函数删除所有子仿真对象对应的场景节点。
[0028] 1-9:移除父仿真对象函数,@name父仿真对象名称,@model父仿真对象, @removeSceneNode是否一并删除场景中节点,bool removeParent(SimuModel* model,bool removeSceneNode),bool removeParent(const string&name,bool removeSceneNode),即输入量为父仿真对象或父仿真对象名称、是否一并删除 场景中节点,输出量为布尔变量值;计算过程为:(1)根据model或name(对 应两个函数)遍历m_pParents列表找到并删除父仿真对象,同时,在父仿真对 象的m_pChildren列表中找到并删除当前仿真对象this;(2)如果 removeSceneNode为真,则调用removeSceneNode()函数删除父仿真对象对应的 场景节点。
[0029] 1-10:移除所有父仿真对象函数,@removeSceneNode是否一并删除场景中 节点,bool SimuModel::removeParents(bool removeScene Node),即输入量 为是否一并删除场景中节点,输出量为布尔变量值,返回0为失败,返回1为 执行成功;计算过程为:(1)遍历m_pParents列表并删除所有父仿真对象;(2) 如果removeSceneNode为真,则调用removeSceneNode()函数删除所有父仿真 对象对应的场景节点。
[0030] 1-11:设置世界坐标位移向量函数,@worldPosition:世界坐标位移向量, void setWorldPosition(osg::Vec3 worldPosition),即输入量为世界坐标位 移向量,无输出量;计算过程为:如果模型m_pObject为真,则利用worldPosition 修改m_pObject的变换矩阵,如果m_pObject为假,则利用 osg::computeWorldToLocal (m_pMatTrans->getParent(0)->getParentalNodePaths()[0]).preMult(world Position),即指将世界坐标位移向量worldPosition转换为局部坐标向量位移localPostion,通过局部坐标变换矩阵m_baseMat的旋转矩阵与更新后的局部 坐标位移矩阵相乘,得到更新后的局部坐标变换矩阵,并赋值给m_baseMat。
[0031] 1-12:设置局部坐标位移向量函数,@localPostion局部坐标位移向量, void setLocalPosition(osg::Vec3 localPostion),即输入量为局部坐标位移 向量,无输出量;计算过程为:如果m_pObject为真,则利用worldPosition 修改m_pObject的变换矩阵,如果m_pObject为假,通过局部坐标变换矩阵 m_baseMat的旋转矩阵与更新后的局部坐标位移矩阵相乘,得到更新后的局部坐 标变换矩阵,并赋值给m_baseMat。
[0032] 1-13:获得局部坐标位移向量函数,osg::Vec3 getLocalPosition(),即 无输入量,输出量为局部坐标位移向量;计算过程为:如果m_pObject为真, 则根据m_pObject->GetTransform(trans,dtCore::Transformable::REL_CS) 即指获得局部坐标变换矩阵trans,然后通过OSG函数库中现有函数 trans.GetTranslation()得到局部坐标位移向量;如果m_pObject为假,则根 据OSG函数库中现有函数m_pMatTrans->getMatrix()获得局部坐标变换矩阵 mat,然后通过OSG函数库中现有函数mat.decompose()分解得到局部坐标位移 向量。
[0033] 1-14:获得世界坐标位移向量函数,osg::Vec3 getWorldPosition(),即 无输入量,输出量为世界坐标位移向量;计算过程为:如果m_pObject为真, 则根据m_pObject->GetTransform(trans,dtCore::Transformable::ABS_CS)获 得世界坐标变换矩阵trans,然后通过trans.GetTranslation()得到世界坐标 位移向量;如果m_pObject为假,则根据m_pMatTrans->getWorldMatrices() 获得世界坐标变换矩阵mat,然后通过mat.decompose()分解得到世界坐标位移 向量。
[0034] 1-15:设置欧拉角函数,@localHPR,worldHPR:heading,pitch,roll in degree(z,x,y),void setLocalHPR(osg::Vec3 localHPR),void setWorldHPR(osg::Vec3 worldHPR),即输入量为局部坐标系下或世界坐标系下 的欧拉角:航向、俯仰、翻滚,heading是实体与z轴的旋转角,pitch是实体 与y轴的旋转角,roll是实体与x轴的旋转角,无输出量;计算过程为:如果 m_pObject为真,根据m_pObject->GetTransform()获得变换矩阵trans,然后 利用localHPR更新trans,最后利用m_pObject->SetTransform()设置更新的 变换矩阵;如果m_pObject为假,则利用具体对象下的函数 m_baseMat.decompose()分解得到旋转矩阵,利用欧拉角HPR更新旋转矩阵并 重新计算得到更新后的变换矩阵mat,最后利用mat对m_baseMat进行赋值。
[0035] 1-16:设置姿态函数,@basePos世界坐标位移向量,@dir世界坐标方位 向量,@localBase局部坐标偏移向量,void setBasePosDir(osg::Vec3& basePos,osg::Vec3&dir,osg::Vec3&localBase),即输入量为世界坐标位 移向量、世界坐标方位向量、局部坐标偏移向量,无输出量;计算过程为:(1) 根据世界坐标方位向量dir,计算世界坐标旋转矩阵OSG现有函数 rotateMatr.makeRotate(osg::PI_2-acos(dir.x()),osg::Vec3(0,1,0), -osg::PI_2+acos(dir.y()),osg::Vec3(1,0,0),0,osg::Vec3(0,0,1)) 和世界坐标旋转逆矩阵osg::Matrix::inverse(rotateMatr);(2)首先,通过 世界坐标旋转逆矩阵inverseRotate与局部坐标下偏移向量localBase相乘, 得到世界坐标偏移向量;然后,计算世界坐标位移向量basePos与世界坐标偏 移向量的差,得到经偏移后的新的世界坐标位移向量;最后,得到经偏移后的 世界坐标位移矩阵。
[0036] 行车与吊车为父子关系、吊车与吊绳为父子关系、吊绳与吊钩为父子关系。 根据行车对象、吊车对象、吊绳对象和吊钩对象的父子从属关系以及行车对象、 吊车对象、吊绳对象和吊钩对象分别与被吊物之间的操作关系,通过继承通用 仿真类构建行车类、吊车类、吊绳类和吊钩类,提供实现行车对象、吊车对象、 吊绳对象和吊钩对象自身在吊装中运动的专有函数;
[0037] 二、定义行车类TrussModel。行车类的专有函数包括:设置配属吊车对象 函数、设置所属厂房对象函数、获得吊车对象列表函数、通过厂房坐标位移向 量设置行车对象在厂房坐标下的移动目标位置函数、增量改变行车对象在厂房 坐标下的位移向量函数、行车对象运动驱动函数。A配属B即B为A的子对象, A为B的父对象;A所属B即B为A的父对象,A为B的子对象。配属吊车对象 即指吊车对象为行车对象的子对象;所属厂房对象即指厂房对象为行车对象的 父对象。
[0038] 设置配属吊车对象函数、设置所属厂房对象函数、获得吊车对象列表函数 通过继承创建树形层级关系函数得到;通过厂房坐标位移向量设置行车对象在 厂房坐标下的移动目标位置函数、增量改变行车对象在厂房坐标下的位移向量 函数通过继承计算空间位置关系函数得到。行车对象运动驱动函数通过继承创 建树形层级关系函数、计算空间位置关系函数得到。
[0039] 2-1:设置配属吊车对象函数,@crane:吊车对象,输出量bool addCrane(CraneModel*crane),即输入量为吊车对象指针,输出量为布尔变 量值,返回0为失败,返回1为执行成功;计算过程为:在吊车对象列表 m_vecCranes中添加吊车对象crane;同时,并将行车对象this赋值给crane 中的行车对象列表m_pTruss。
[0040] 2-2:设置所属厂房对象函数,@mat:厂房节点变换矩阵,bool setFactory (osg::MatrixTransform*mat)osg指变换矩阵类型,输入量为厂房对象节点 变换矩阵,输出量为布尔变量值,返回0为失败,返回1为执行成功;计算过 程为:(1)将mat赋值给厂房对象节点变换矩阵指针列表m_pFactoryMat;(2) 将厂房对象世界坐标变换矩阵赋值给厂房对象世界坐标变换矩阵列表 m_worldFactoryMatrix;(3)将厂房对象世界坐标变换逆矩阵赋值给厂房对象 世界坐标变换逆矩阵列表m_worldFactoryInverseMatrix。
[0041] 2-3:获得吊车对象列表函数,@cranes:吊车对象列表,bool getCranes (vector&cranes),vector表示向量、数组类型,CraneModel* 表示吊车对象指针,&cranes表示吊车对象列表地址,即输入量为吊车对象列 表,输出量为布尔变量值,返回0为失败,返回1为执行成功;计算过程为: 通过遍历吊车对象列表m_vecCranes得到。
[0042] 2-4:通过厂房坐标位移向量设置行车对象在厂房坐标下的移动目标位置函 数,@factroyPos:厂房坐标位移向量,@style:运动后继,0表示运动完成后 不启动其它运动,1代表吊车,2代表吊钩,void setMoveFinPosByFactoryPos(const osg::Vec3&factoryPos,int style),即 输入量为厂房坐标位移向量、运动后继,无输出量;计算过程为:如果行车对 象在X方向上移动m_vecMoveDir.x()不为零,则将厂房坐标位移向量X方向分 量factoryPos.x赋值给行车在厂房坐标下的终点位移向量X方向分量 m_vecFinPos.x()(m_vecFinPos为行车在厂房坐标下的终点位移向量),否则, 将厂房坐标位移向量Y方向分量factoryPos.y赋值给行车在厂房坐标下的终点 位移向量Y方向分量m_vecFinPos.y()。
[0043] 2-5:增量改变行车对象在厂房坐标下的位移向量函数,@delta增量向量, void setPositionByDelta(const float delta),即输入量为增量向量,无输 出量;计算过程为:(1)更新行车对象的厂房坐标位移向量m_vecCurPos,如果m_vecMoveDir.x()不为零,则对行车对象在厂房坐标下的位移向量X方向分量 m_vecCurPos.x(m_vecCurPos为行车对象在厂房坐标下的位移向量)增加该增 量向量X方向分量delta.x(),否则,对行车对象在厂房坐标下的位移向量Y 方向分量m_vecCurPos.y()增加该增量向量Y方向分量delta.y();(2)通过 行车对象的厂房坐标旋转矩阵和移动后的厂房坐标位移矩阵的乘积,得到移动 后的行车对象的厂房坐标变换矩阵matr;(3)设置行车对象移动后的厂房坐标 变换矩阵setMatrix(matr)。
[0044] 2-6:行车对象运动驱动函数,每帧调用,void task()。无输入、输出量; 计算过程为:
[0045] 步骤2-6-1:行车对象若不存在,退出。
[0046] 步骤2-6-2:若运动未完成:
[0047] 步骤2-6-2-1:如果行车对象在厂房坐标下的x方向移动m_vecMoveDir.x() 不为零,将m_vecCurPos.x()赋值给当前位置Cur,m_vecFinPos.x()赋值给终 点位置Des;如果行车对象在厂房坐标下的x方向移动m_vecMoveDir.x()为零, 则将m_vecCurPos.y()赋值给Cur,m_vecFinPos.y()赋值给Des。
[0048] 步骤2-6-2-2:若des大于cur,Cur记为Cur+当前行车速度/当前帧数; 如果当前位置与终点位置相差0.0001以内,将当前位置置为终点位置并将运动 状态设为停止。若Des小于Cur,Cur记为Cur-当前行车速度/当前帧数;如果 终点位置与当前位置相差0.0001以内,将当前位置置为终点位置并将运动状态 设为停止。
[0049] 步骤2-6-2-3:如果行车对象在x方向上有运动,则将m_vecCurPos.x()置 为cur,否则将m_vecCurPos.y()置为cur。
[0050] 步骤2-6-2-4:更新行车对象的厂房坐标变换矩阵,m_pMat ->setMatrix(osg::Matrix::rotate(m_pMat->getMatrix().getRotate())* osg::Matrix::translate(m_vecCurPos)),即行车对象的厂房坐标旋转矩阵乘 以移动后的厂房坐标位移矩阵得到更新后的行车对象的厂房坐标变换矩阵。
[0051] 步骤2-6-2-5:如果当前运动中止并且有下一步动作时,当动作代码为1时, 设置迭代器auto iter=m_vecCranes.begin(),将吊车对象列表中的第一个吊 车对象定义为iter,即从吊车对象列表中的第一个吊车对象开始遍历;遍历吊 车列表m_vecCranes,并将吊车列表中每个吊车对象的运动状态设置为未完成。 当动作代码为2时,设置citer为吊绳对象的迭代器auto citer= (*iter)->m_vecRopes.begin();遍历吊绳列表m_vecRopes,并将每个下属吊车 吊绳的运动状态设置为未完成。下属即配属。
[0052] 步骤2-6-3:行车对象运动已经完成:设置迭代器auto  iter=  m_vecCranes.begin(),遍历下属吊车对象,执行吊车类的3-9吊车对象运动驱 动函数task()即(*iter)->task()。
[0053] 三、定义吊车类CraneModel。吊车类的专有函数包括:设置所属行车对象 函数、设置配属吊绳对象函数、获得指定编号的吊绳对象函数、通过行车坐标 位移向量设置吊车在行车坐标下的终点位移向量函数、通过厂房坐标位移向量 设置吊车对象在行车坐标下的移动目标位置函数、获得指定吊钩对象的兄弟吊 钩对象函数、获得主吊钩对象函数、增量设置吊车对象在行车坐标下的位移向 量函数、吊车对象运动驱动函数。
[0054] 设置所属行车对象函数、设置配属吊绳对象函数、获得指定编号的吊绳对 象函数、获得指定吊钩对象的兄弟吊钩对象函数、获得主吊钩对象函数通过继 承创建树形层级关系函数得到;通过行车坐标位移向量设置吊车在行车坐标下 的终点位移向量函数、通过厂房坐标位移向量设置吊车对象在行车坐标下的移 动目标位置函数、增量设置吊车对象在行车坐标下的位移向量函数通过继承计 算空间位置关系函数得到。吊车对象运动驱动函数通过继承创建树形层级关系 函数、计算空间位置关系函数得到。
[0055] 3-1:设置所属行车对象函数,@truss:所属行车对象,bool setTruss(TrussModel*truss),即输入量为所属行车对象指针,输出量为布尔 变量值,返回0为失败,返回1为执行成功;计算过程为:首先,将行车对象 truss赋值给吊车对象的m_pTruss,其次,在行车对象truss的吊车对象列表 中添加该吊车对象this。
[0056] 3-2:设置配属吊绳对象函数,@rope:吊绳对象,bool addRope(RopeModel* rope),即输入量为吊绳对象,输出量为布尔变量值,返回0为失败,返回1 为执行成功;计算过程为:首先,在吊车的吊绳对象列表m_vecRopes中添加rope, 其次,将this赋值给吊绳对象中的m_pCrane。
[0057] 3-3:获得指定编号的吊绳对象函数,@i:吊绳编号,RopeModel*getRope(int i),即输入量为吊绳编号,输出量为指定编号的吊绳对象;计算过程为:在吊 车的吊绳对象列表m_vecRopes中按序号查找名返回吊绳对象,return m_vecRopes[i]。
[0058] 3-4:通过行车坐标位移向量设置吊车在行车坐标下的终点位移向量函数, @pos行车坐标终点位移向量,@style运动后继,0表示运动完成后不启动其它 运动,1代表吊车,2代表吊钩,void setMoveFinPosByLocalPos(const osg::Vec3&pos,int style),即输入量为行车坐标终点位移向量、运动后 继,运动后继包括运动完成后不启动其它运动、吊车运动及吊钩运动;无输出 量;计算过程为:如果m_vecMoveDir.x()不为零(表示行车对象在X方向上移 动),则将行车对象位移向量X方向分量pos.x赋值给m_vecFinPos.x() (m_vecFinPos为吊车对象在行车坐标下的终点位移向量),否则,将行车对象 位移向量Y方向分量pos.y赋值给m_vecFinPos.y()。
[0059] 3-5:通过厂房坐标位移向量设置吊车对象在行车坐标下的移动目标位置函 数,@factroyPos厂房坐标位移向量,@style运动后继,0表示运动完成后不 启动其它运动,1代表吊车,2代表吊钩,void setMoveFinPosByFactoryPos(const osg::Vec3&factoryPos,RopeModel*rp, int style),即输入量为厂房坐标位移向量、运动后继,运动后继包括运动完 成后不启动其它运动、行车运动及吊钩运动,无输出量;计算过程为:(1)将 厂房坐标位移向量factoryPos与行车对象在厂房坐标下的变换逆矩阵 getTruss()->getInverseMatrix()相乘,得到行车坐标位移向量 localPosition;(2)减去吊绳对象坐标基准点相对于吊车对象坐标基准点的偏 差,其中,rp为吊绳对象,localPosition.x()-=rp->getRopeDis(), localPosition.y()-=rp->getRopeDis();(3)调用函数通过行车坐标位移向 量设置吊车在行车坐标下的终点位移向量函数setMoveFinPosByLocalPos (localPosition,style)完成设置。
[0060] 3-6:获得指定吊钩对象的兄弟吊钩对象函数,@hook:兄弟吊钩对象,@i: 兄弟吊钩编号,HookModel*getHookSibling(HookModel*hook,int i),即 输入量为兄弟吊钩对象、兄弟吊钩编号,输出量为指定吊钩对象的兄弟吊钩对 象;计算过程为:遍历吊车对象包含的所有吊绳对象iter,对吊绳对象包含的 吊钩对象与hook比较,if((*iter)->getHook()!=hook),则return (*iter)->getHook(),即如果为真则返回指定吊钩对象的兄弟吊钩对象。
[0061] 3-7:获得主吊钩对象函数,HookModel*getPrimeHook(),即无输入量, 输出量为主吊钩对象;计算过程为:首先,遍历吊车对象包含的所有吊绳对象 iter,对吊绳对象包含的吊钩对象与主吊钩对象比较,if ((*iter)->getHook()->getPrime()),则return(*iter)->getHook(),即如果 为真则返回主吊钩对象。
[0062] 3-8:增量设置吊车对象在行车坐标下的位移向量,在移动吊车时调用, @delta增量,void CraneModel::setPositionByDelta(const float delta)。 即输入量为增量向量,无输出量;具体过程参考行车。计算过程为:更新吊车 对象的行车坐标位移向量,如果吊车对象在X方向上移动不为零,则对吊车对 象在行车坐标下的位移向量X方向分量增加所述增量向量,否则,对吊车对象 在行车坐标下的位移向量Y方向分量增加所述增量向量;通过吊车对象的行车 坐标旋转矩阵和移动后的行车坐标位移矩阵的乘积,得到移动后的吊车对象的 行车坐标变换矩阵;设置吊车对象移动后的行车坐标变换矩阵即为赋值过程。
[0063] 3-9:吊车对象运动驱动函数,void task()。无输入、输出量;计算过程 为:
[0064] 步骤3-9-1:若节点不存在,退出。
[0065] 步骤3-9-2:若运动未完成:
[0066] 步骤3-9-2-1:如果吊车对象在行车坐标下x方向移动m_vecCurPos.x()不 为零,则当前位置Cur存储当前x位置m_vecCurPos.x(),终点位置Des存储终 点x位置m_vecFinPos.x();如果吊车对象在行车坐标下X方向移动为零,则 Cur存储当前y位置m_vecCurPos.y(),Des存储终点y位置m_vecFinPos.y()。
[0067] 步骤3-9-2-2:若des大于cur,则Cur记为Cur+当前吊车速度/当前帧数, 如果当前位置与终点位置相差0.0001以内,将当前位置置为终点位置并将运动 状态设为停止;若Des小于Cur,则Cur记为Cur-当前行车速度/当前帧数,如 果终点位置与当前位置相差0.0001以内,将当前位置置为终点位置并将运动状 态设为停止。
[0068] 步骤3-9-2-3:如果吊车对象在x方向上有运动,将吊车对象在行车坐标下 的位移向量X方向分量置为cur,否则将吊车对象在行车坐标下的位移向量Y方 向分量置为cur。
[0069] 步骤3-9-2-4:计算吊车对象的行车坐标旋转矩阵与移动后的行车坐标位移 矩阵的乘积,计算得到的吊车对象移动后的行车坐标变换矩阵。
[0070] 步骤3-9-2-5:如果当前运动中止并且有下一步动作时,当前动作代码为1 时,设置吊车对象运动未结束。当前动作代码为2时,遍历,设置citer为吊 绳对象的迭代器;遍历吊钩对象列表,并将每个下属吊钩对象的运动状态设置 为未完成;将下一步动作设置为0。
[0071] 步骤3-9-3:设置吊绳对象的迭代器,遍历,执行吊钩类的task(),即执 行5-10:吊钩对象运动驱动函数。
[0072] 四、定义吊绳类RopeModel。吊绳类的专有函数包括:获得所属行车对象函 数、设置所属吊车对象函数、设置配属吊钩对象函数、更新吊绳对象函数、吊 绳对象运动驱动函数。
[0073] 获得所属行车对象函数、设置所属吊车对象函数、设置配属吊钩对象函数、 通过继承创建树形层级关系函数得到。更新吊绳对象函数通过计算空间位置关 系函数得到。吊绳对象运动驱动函数通过继承创建树形层级关系函数、计算空 间位置关系函数得到。
[0074] 4-1:获得所属行车对象函数,TrussModel*getTruss(),即无输入量,输 出量为所属行车对象;计算过程为:return m_pCrane->getTruss(),m_pCrane 是吊绳对象中的定义的所属吊车对象,根据吊绳对象中的所属吊车对象获得所 属行车对象。
[0075] 4-2:设置所属吊车对象函数,@crane:吊车对象,bool setCrane (CraneModel*crane),即输入量为吊车对象,输出量为布尔变量值,返回0为 失败,返回1为执行成功;计算过程为:首先,将吊车对象赋值给吊绳对象的 吊车对象列表,同时在吊车对象的吊绳对象列表中添加吊绳对象;其次,如果 m_pCrane->getMoveDirection().x()>0.5吊车对象在X方向上移动大于0.5, 则将m_pMat变换矩阵中位移向量的X方向分量赋值给吊绳对象的移动距离 m_fRopeDis,m_fRopeDis=m_pMat->getMatrix().getTrans().x(),否则, m_fRopeDis=m_pMat->getMatrix().getTrans().y()将m_pMat变换矩阵中位 移向量的Y方向分量赋值给吊绳对象的移动距离m_fRopeDis,其中,m_pMat为 吊绳对象的变换矩阵指针;接着,如果不存在吊绳节点,则创建吊绳节点,如 果存在吊绳节点,则将吊绳节点从所有父节点中移除;最后,获取吊车对象的 变换矩阵指针,并将吊绳节点添加到吊车对象的变换矩阵指针的子节点中。
[0076] 4-3:设置配属吊钩对象函数,@hook:吊钩对象,bool setHook(HookModel* hook),即输入量为吊钩对象,输出量为布尔变量值,返回0为失败,返回1为 执行成功;计算过程为:将吊钩对象hook赋值给吊绳对象的吊钩对象列表 m_pHook,同时将该吊绳对象this赋值给吊钩对象列表m_pHook的吊绳对象列 表m_pRope。
[0077] 4-4:更新吊绳对象函数,void draw(),即无输入量,无输出量。计算过 程为:(1)获取吊绳对象的吊车坐标位移向量和所属吊钩对象的吊车坐标位移 向量,并分别赋值给吊绳始端点start、吊绳终端点end,作为吊绳模型端点的 吊车坐标位移向量;(2)创建更新后的吊绳节点m_pRopeGeode、吊绳模型geom 和端点列表vertices,首先对两个端点进行赋值, vertices->push_back(start),vertices->push_back(end),然后对吊绳模型 geom进行端点列表vertices赋值geom->setVertexArray(vertices.get()); (3)对吊绳模型geom进行颜色、类型和属性赋值;(4)在吊绳节点m_pRopeGeode 中添加吊绳模型,函数为geom.get()。
[0078] 4-5:吊绳对象运动驱动函数,void task(),即无输入、输出量;计算过 程为:
[0079] 步骤4-5-1:如果吊钩对象m_pHook存在,执行m_pHook->task(),即执行 属于吊绳对象的吊钩对象运动驱动函数。
[0080] 步骤4-5-2:执行draw(),即执行更新吊绳对象函数。
[0081] 五、定义吊钩类,HookModel。吊钩类的专有函数包括:设置所属吊绳对象 函数、获得所属行车对象函数、获得所属吊车对象函数、设置对接点函数、吊 具对象移动函数、绑定被吊物对象函数、释放被吊物对象函数、主吊钩对象向 上移动函数、通过厂房坐标位移向量设置吊钩对象在吊车坐标下的移动目标位 置函数、吊钩对象运动驱动函数。
[0082] 设置所属吊绳对象函数、获得所属行车对象函数、获得所属吊车对象函数、 设置对接点函数、绑定被吊物对象函数、释放被吊物对象函数通过继承创建树 形层级关系函数得到;通过厂房坐标位移向量设置吊钩对象在吊车坐标下的移 动目标位置函数通过继承计算空间位置关系函数得到;吊具对象移动函数、主 吊钩对象向上移动函数通过继承创建树形层级关系函数、计算空间位置关系函 数得到。
[0083] 5-1:设置所属吊绳对象函数,@rope:所属的吊绳对象,bool setRope(RopeModel*rope),即输入量为所属的吊绳对象,输出量为布尔变量 值,返回0为失败,返回1为执行成功;计算过程为:将所属的吊绳对象rope 赋值给吊钩对象中的吊绳对象m_pRope,并将吊钩对象this赋值给吊绳对象的 吊钩对象m_pHook。
[0084] 5-2:获得所属行车对象函数,TrussModel*getTruss(),即无输入量,输 出量为所属行车对象;计算过程为:通过吊钩对象中的吊绳对象m_pRope获得 行车对象m_pRope->getTruss()。
[0085] 5-3:获得所属吊车对象函数,CraneModel*getCrane(),即无输入量,输 出量为所属吊车对象;计算过程为:通过吊钩对象中的吊绳对象m_pRope获得 吊车对象m_pRope->getCrane()。
[0086] 5-4:设置对接点函数,@hp:对接点变换矩阵指针,bool setHookPoint (osg::MatrixTransform*hp),即输入量为对接点变换矩阵指针,输出量为布 尔变量值,返回0为失败,返回1为执行成功;计算过程为:将对接点变换矩 阵指针hp赋值给吊钩对象的对接点变换矩阵指针m_pHookPoint。
[0087] 5-5:吊具对象移动函数,吊具对象指在吊钩上勾着的吊具,@obj:吊具对 象,@delta:增量向量,void hookToolMove(SimuModel*obj,osg::Vec3 delta), 即输入量为吊具对象、增量向量,无输出量;计算过程为:(1)获取被吊物列 表m_vecHangObjects中的倒数第二个对象*(m_vecHangObjects.end()-1),即 与吊具对象连接的被吊物对象model;(2)通过该被吊物对象的世界坐标变换矩 阵model->getMatrix Transform()->getWorld Matrices()[0]与对接基准点(吊 具吊绳与该被吊物连接面中心点)在该被吊物坐标下的位移向量 m_vecHookObjectBase相乘,得到被吊物对象对接基准点的世界坐标位移向量basePos;(3)如果是主吊钩,首先计算对接基准点在吊具坐标下的位移向量; 然后,计算被吊物对象对接基准点的世界坐标位移向量basePos;否则,首先, 计算吊具对象移动后的世界坐标位移向量,然后,通过被吊物对象对接基准点 的世界坐标位移向量与吊具对象移动后的世界坐标变换逆矩阵相乘,得到被吊 物对象对接基准点在移动后的吊具坐标下的位移向量localBase;(4)计算吊绳 对象的世界坐标位移向量ropePos与被吊物对象对接基准点的世界坐标位移向 量basePos的差,得到吊具方位向量direction;(5)利用basePos,direction, localBase设定吊具对象的姿态。
[0088] 5-6:绑定被吊物对象函数,@obj:被吊物对象,bool hangObject (SimuModel*obj),即输入量为被吊物对象,输出量为布尔变量值,返回0为 失败,返回1为执行成功;计算过程为:(1)将被吊物体对象添加到吊钩对象 的m_vecHangObjects列表中;(2)获取吊钩对象和被吊物对象的世界坐标位移 向量;(3)获取被吊物对象下对接基准点的局部坐标位移向量;(4)如果被吊 物对象下对接基准点局部坐标位移向量不为零,计算吊钩对象坐标基准点(吊钩 对象坐标系下坐标原点)和被吊物对象下对接基准点的世界坐标位移向量差,否 则,计算吊钩对象坐标基准点和被吊物对象坐标基准点(被吊物对象坐标系下 坐标原点)的世界坐标位移向量差;(5)计算吊具对象长度;(6)计算被吊物 对象在吊钩坐标下的位移向量;(7)遍历所有被吊物对象列表 m_vecHangObjects(当前被吊物除外),通过对接基准点的世界坐标位移向量 basePos与被吊物对象世界坐标变换逆矩阵相乘,得到对接基准点在被吊物坐标 下的位移向量localBase,并将其赋值给该被吊物对象的被吊物对象对接基准点 列表m_vecHookToolBase。
[0089] 5-7:释放被吊物对象函数,bool releaseObject(),即无输入量,输出量 为布尔变量值;计算过程为:计算吊钩对象的世界坐标位移向量与对接基准点 在吊钩坐标下的偏移向量,计算得到对接基准点的世界坐标位移向量,如果对 接基准点与被吊物对象的坐标基准点重合,那么对接基准点的世界坐标位移向 量就是被吊物对象的世界坐标位移向量;如果不重合,在对接基准点的世界坐 标位移向量基础上,加上对接基准点与被吊物对象坐标基准点的差,才能得到 被吊物对象的世界坐标位移向量。
[0090] 5-8:主吊钩对象向上移动函数,@delta:增量值,void primeHookMoveUp(float delta),即输入量为增量值,无输出量;计算过程为: (1)获取吊绳对象的世界坐标位移向量和对接基准点的世界坐标位移向量; (2)计算对接基准点在Z方向上的位移分量;(3)根据吊绳的方位和吊具长度 计算吊钩对象移动后的世界坐标位移向量;(4)获取吊车对象的世界坐标变换 逆矩阵;(5)计算并设置吊钩对象在吊车坐标下的位移向量。
[0091] 5-9:通过厂房坐标位移向量设置吊钩对象在吊车坐标下的移动目标位置函 数,@postion厂房坐标位移向量,@style运动后继,0表示运动完成后不启动 其它运动,1代表吊车,2代表吊钩,void setMoveFinPos ByFactoryPos(const osg::Vec3&postion,int style),即输入量为厂房坐标位移向量、运动后继, 无输出量;计算过程为:(1)将厂房坐标位移向量postion保存在厂房坐标目 标位移向量列表m_vecFinFactoryPos中;(2)通过行车对象厂房坐标变换逆矩 阵*吊车对象行车坐标变换逆矩阵*postion,计算得到吊车坐标位移向量 localPos;(3)将运动后继style赋值给下一步动作变量m_dNextMove,将吊 车坐标Z方向位移向量localPos.z()赋值给吊车坐标位移向量Z方向分量 m_vecFinPos.z()。
[0092] 5-10:吊钩对象运动驱动函数,void task()。无输入、输出量;计算过程 为:
[0093] 步骤5-10-1:若当前运动状态处于垂直面内的旋转VROTATE:获得主吊钩 对接基准点移动前的世界坐标位移向量m_vecWorldBasePos;通过增加步长,获 得主吊钩对接基准点移动后的世界坐标位移向量m_vecWorldBasePos(移动前和 移动后的世界坐标位移向量均存储在m_vecWorldBasePos中,在程序应用里一 个变量可以存储不同时刻的向量值);通过计算主吊钩对接基准点与吊车对象的 世界坐标位移向量的差,得到被吊物对象的方位向量direction;根据主吊钩对 接基准点、方向向量、吊具长度可以求得主吊钩对象的世界坐标位移向量 hookPos;计算主吊钩对象的世界坐标位移向量与吊车对象世界坐标的变换逆矩 阵,得到主吊钩对象在吊车坐标下的位移向量;被吊物对象离地高度增加一个 步长,根据勾股定理,求得主吊钩对接基准点与被吊物重心点之间的水平距离; 根据主吊钩对接基准点世界坐标位移向量求得被吊物重心点的世界坐标位移向  量m_
vecCentroidPos;求得重心点后,协同主吊钩对接基准点世界坐标位移向 量解算出副吊钩对接基准点世界坐标位移向量。与主吊钩位置计算方法类似, 使用方向向量和吊具长度求解并设置副吊钩对象位置与姿态。
[0094] 步骤5-10-2:若当前运动状态处于水平面内的旋转HROTATE:(1)根据旋 转角度,计算旋转矩阵:如果水平旋转角度为正,设置步长为水平旋转角度减 去当前旋转角度;如果步长大于1,将步长置1;否则,设置运动状态为以结束; 旋转过一个步长的弧度。如果水平旋转角度为负,设置步长为水平旋转角度减 去当前旋转角度;如果步长小于-1,将步长置-1;否则,设置运动状态为以结 束;旋转过一个步长的弧度。(2)根据旋转矩阵,计算主吊钩旋转后的世界坐 标变换矩阵和所有被吊物旋转后的世界坐标变换矩阵。
[0095] 步骤5-10-3:如果不是主吊钩,并且处于调整吊绳状态ADJUSTROPE或者MOVE移动动作状态,同时与主吊钩吊起同一被吊物:将主吊钩运动状态设置为 结束,倾斜吊绳,goto TASKEND进行步骤5-10-6即更新吊钩对象在吊车坐标下 的位移向量和被吊物对象状态。
[0096] 步骤5-10-4:如果处于ADJUSTROPE状态:倾斜吊绳;如果吊车和行车的运 动状态均为结束,则将吊钩状态设置为结束。
[0097] 步骤5-10-5:如果处于MOVE状态,并且吊车处于结束运动状态:(1)当主、 副吊钩没有吊起同一被吊物。如果结束运动标识m_bMoveFinish为假,更新吊 钩对象在Z方向上移动后的在吊车坐标下的变换矩阵,如果到达目标位置,则 结束运动标识m_bMoveFinish设为真;各个对象运动有先后顺序,行车运动完, 吊车运动;吊车运动完,吊绳运动;如果结束运动标识置m_bMoveFinish为真, 当m_dNextMove==1时,将行车结束运动标识置为假,当m_dNextMove==2时, 将吊车结束运动标识置为假。(2)当主、副吊钩吊起同一被吊物。如果结束运 动标识m_bMoveFinish为假,调用主吊钩对象向上移动函数primeHookMoveUp() 移动主吊钩对象。
[0098] 步骤5-10-6:TASKEND:更新吊钩对象在吊车坐标下的位移向量和被吊物对 象状态。
[0099] 六、定义吊装类,Truesses。提供驱动行车类、吊车类、吊绳类和吊钩类 对象、协同实现吊装工艺流程的专有函数;吊装类的专有函数包括:分析厂房 对象函数、吊钩与吊绳对象配对函数、获取吊钩对象函数、获取行车对象函数、 吊装驱动函数、移动至目标位置函数、绑定被吊物对象函数、释放被吊物对象 函数。
[0100] 分析厂房对象函数、吊钩与吊绳对象配对函数、获取吊钩对象函数、获取 行车对象函数、绑定被吊物对象函数、释放被吊物对象函数通过继承创建树形 层级关系函数得到;吊装驱动函数、移动至目标位置函数通过继承创建树形层 级关系函数、计算空间位置关系函数得到。
[0101] 6-1:分析厂房对象函数,@factory:厂房对象变换矩阵指针,void parseFactory(osg::MatrixTransform*factory),即输入量为厂房对象变换 矩阵指针,无输出量;计算过程为:遍历厂房对象变换矩阵指针factory的子 节点查找是否存在行车节点变换矩阵指针trussNode,如果存在则创建行车对象 trussmodel,并保存在行车对象列表m_vecTrusses中,并将factory赋值给创 建的行车对象的厂房对象变换矩阵指针列表m_pFactoryMat;查找trussNode子 节点中是否存在吊车节点craneNode,存在则创建吊车对象cranemodel,并将 trussmodel赋值给cranemodel的行车对象列表m_pTruss;遍历craneNode的 子节点是否存在吊钩节点hookNode,如果存在则创建吊钩对象hookmodel,将 hookmodel保存在吊钩对象名称映射列表m_mapNameToHooks中,并读取设置吊 钩对接基准点;遍历craneNode的子节点是否存在吊绳节点,存在则创建吊绳 对象ropemodel,将cranemodel赋值给ropemodel的吊车对象列表m_pCrane, 并将cranemodel保存在吊绳对象名称映射列表m_mapNameToRopes中。
[0102] 6-2:吊钩与吊绳对象配对函数,void mapRopeAndHook(),即无输入量, 无输出量;计算过程为:遍历m_mapNameToRopes,获取吊绳对象ropemodel, 根据吊绳对象名称前缀生成吊钩名称,并在m_mapNameToHooks中获取吊钩对象 hookmodel,将hookmodel赋值给ropemodel的吊钩对象列表m_pHook,并调用 更新吊绳对象函数draw()绘制吊绳。
[0103] 6-3:获取吊钩对象函数,@name:吊钩名称,HookModel* getHookByName(const string&name),即输入量为吊钩名称,输出量为吊钩 对象;计算过程为:在吊钩对象名称映射列表m_mapNameToHooks中根据吊钩名 称name查找。
[0104] 6-4:获取行车对象函数,@hook:吊钩对象,@hookName:吊钩名称, TrussModel*getTrussByHook(HookModel*hookmodel),TrussModel* getTrussByHook(const string&hookName),即输入量为吊钩名称,输出量 为行车对象;计算过程为:前者函数通过吊钩类的5-2获得所属行车对象函数 hookmodel->getTruss()获得。后者函数通过遍历吊钩对象名称映射列表 m_mapNameToHooks获得吊钩对象hookmodel,然后利用吊钩对象hookmodel通 过前者函数getTrussByHook(hookmodel)获得行车对象。
[0105] 6-5:吊装驱动函数,void task(),无输入、输出量。计算过程为:遍历 m_vecTrusses行车对象列表得到行车对象,并调用该行车对象的task()行车对 象驱动函数。
[0106] 6-6:移动至目标位置函数,@hookname:吊钩名称,@position:厂房坐 标下目标位移向量,@sstyle:三个对象的运动顺序,0:行车-吊车-吊钩,1: 行车-吊钩-吊车,2:吊车-行车-吊钩,3:吊车-吊钩-行车,4:吊钩-行车-吊 车,5:吊钩-吊车-行车,@vel:运动速度,void moveToTargetPosition(const string&hookname,const osg::Vec3&position,int sstyle,float vel), 即输入量为吊钩名称、厂房坐标下目标位移向量、三个对象的运动顺序、运动 速度,无输出量;计算过程为:(1)根据hookname在m_mapNameToHooks列表 中得到吊钩对象hookmodel,根据吊钩在Z方向上与厂房坐标目标位移向量的偏 差,计算得到吊钩对象在厂房坐标下的目标位移向量;(2)获取行车对象 trussmodel、吊车对象cranemodel;(3)将position保存在吊钩对象的厂房坐 标目标位移向量列表m_vecFinFactoryPos中;
(4)调用通过厂房坐标位移向量  设置行车对象在厂房坐标下的移动目标位置函数trussmodel->setMoveFinPosByFactoryPos(position,sstyle1);调用通过厂 房坐标位移向量设置吊车对象在行车坐标下的移动目标位置函数  cranemodel->
setMoveFinPosByFactoryPos(position,hookmodel->getRope(), sstyle2);如果position.z()>=0即厂房坐标下目标位移向量Z方向分量大于0 成立,调用通过厂房坐标位移向量设置吊钩对象在吊车坐标下的移动目标位置 函数hookmodel->setMoveFinPos ByFactoryPos(position,sstyle3);行车移 动结束标识设为假,trussmodel->setMoveFinished(false)。
[0107] 6-7:绑定被吊物对象函数,@hook吊钩名称,@object被吊物对象,在 调用该函数之前,应当已经通过吊钩对象移动将被吊物对象放在应在的位置上, 调用该函数将会使吊钩和被吊物对象产生关联,void hangObject(const string&hookname,SimuModel*object),即输入量为吊钩名称、被吊物对象, 输出量为布尔变量值,返回0为失败,返回1为执行成功;计算过程为:根据 hookname在m_mapNameToHooks列表中得到吊钩对象hookmodel,调用 hookmodel->hangObject(object)吊钩对象的5-6绑定被吊物对象函数执行绑定 被吊物对象操作。
[0108] 6-8:释放被吊物对象函数,@hook吊钩名称,在调用该函数之前,应当已 经通过吊钩对象移动将被吊物放在应在的位置上,调用该函数将会解绑吊钩和 被吊物对象之间的关联,void releaseObject(const string&hookname),即 输入量为吊钩名称,输出量为布尔变量值,返回0为失败,返回1为执行成功;  计算过程为:根据hookname在m_mapNameToHooks列表中得到吊钩对象 hookmodel,调用hookmodel->releaseObject()吊钩对象的5-6绑定被吊物对 象函数执行释放被吊物对象操作。
[0109] 综上所述,以上仅为本发明的较佳实施例而已,并非用于限定本发明的保 护范围。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等, 均应包含在本发明的保护范围之内。

当前第1页 第1页 第2页 第3页
相关技术
吊装工艺流程相关技术
对象吊装相关技术
吴枫发明人的其他相关专利技术