通过在史陶比尔官网下载TX90机械臂模型,经过UG进行坐标转换,creo导成iv格式,最后导入Coin3D中,模型如图所示:
主要步骤如下:
1.通过UG移动零件本身,将世界坐标系移至运动副。以连杆arm为例
装配中,arm 的Y轴和Z轴应如上图所示,而零件中,arm的世界坐标如下图:
通过UG的坐标转换,首先要建立绝对坐标系,通过移动或旋转零件使其满足装配下的坐标系:
移动零件或旋转零件操作如下:
导成iv格式放入程序中,读取arm的程序如下
SoSeparator* TX90robot::makeRod2()
{
SoSeparator* tx90_arm = new SoSeparator;
m_rot2->axis = SoRotationXYZ::Y;
SoTransform* form2 = new SoTransform;
form2->translation.setValue(0.05, 0.160, 0.230);
SoInput inputAxis2;
inputAxis2.openFile("tx90_arm.iv");
SoSeparator* mygraph = SoDB::readAll(&inputAxis2);
mygraph->ref();
tx90_arm->addChild(form2);
tx90_arm->addChild(m_rot2);
tx90_arm->addChild(mygraph);
return tx90_arm;
}
其中 m_rot2->axis = SoRotationXYZ::Y;表示为绕Y轴旋转,也是为什么要把坐标系放到运动副的原因
form2->translation.setValue(0.05, 0.160, 0.230);为ARM的坐标系相对shouder的坐标系,这样shouder旋转,arm也会相应旋转,shouder里的坐标系数据如图:
同理依次变换测量其他连杆,最后装配如下:
//按相对坐标 Rod0->addChild(Rod1);表示在ROd0坐标系中组装
robot->addChild(Rod0);
Rod0->addChild(Rod1);
Rod1->addChild(Rod2);
Rod2->addChild(Rod3);
Rod3->addChild(Rod4);
Rod4->addChild(Rod5);
Rod5->addChild(Rod6);
root->addChild(robot);
其中 Rod0->addChild(Rod1);表示在rod1在ROd0坐标系中组装,是相对Rod0的。
完整的robot类头文件如下:
#pragma once
#include "stdafx.h"
#include <Inventor/Win/SoWin.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/nodes/SoRotationXYZ.h>
#include <Inventor/nodes/SoRotor.h>
#define PI 3.14159265358979323846
class TX90robot
{
public:
TX90robot(void);
~TX90robot(void);
public:
SoSeparator *root;
//旋转轴
SoRotationXYZ *m_rot1;
SoRotationXYZ *m_rot2;
SoRotationXYZ *m_rot3;
SoRotationXYZ *m_rot4;
SoRotationXYZ *m_rot5;
SoRotationXYZ *m_rot6;
SoSeparator * makeRod0();
SoSeparator * makeRod1();
SoSeparator * makeRod2();
SoSeparator * makeRod3();
SoSeparator * makeRod4();
SoSeparator * makeRod5();
SoSeparator * makeRod6();
void makeScene();
};
实现文件如下:
#include "stdafx.h"
#include "TX90robot.h"
TX90robot::TX90robot(void)
{
m_rot1 = new SoRotationXYZ;
m_rot2 = new SoRotationXYZ;
m_rot3 = new SoRotationXYZ;
m_rot4 = new SoRotationXYZ;
m_rot5 = new SoRotationXYZ;
m_rot6 = new SoRotationXYZ;
}
TX90robot::~TX90robot(void)
{
}
SoSeparator* TX90robot::makeRod0()
{
SoSeparator* base = new SoSeparator;//因为函数要返回soseparator*类型
SoTransform* form0 = new SoTransform;
form0->translation.setValue(0, 0, 0);
SoInput inputbase;
inputbase.openFile("tx90_horizontal_base_cable_outl.iv");
SoSeparator *mygraph = SoDB::readAll(&inputbase);
mygraph->ref();
base->addChild(form0);
base->addChild(mygraph);
return base;
}
SoSeparator* TX90robot::makeRod1()
{
SoSeparator* tx90_shoulder = new SoSeparator;//因为函数要返回soseparator*类型
tx90_shoulder->ref();
SoTransform* form1 = new SoTransform;
form1->translation.setValue(0, 0, 0.24801);//导入的模型记录了建立的原点,通过装配体测两零件间的坐标系原点距离
m_rot1->axis = SoRotationXYZ::Z;
SoInput inputAxis1;
inputAxis1.openFile("tx90_shoulder.iv");
SoSeparator *mygraph = SoDB::readAll(&inputAxis1);
mygraph->ref();
tx90_shoulder->addChild(form1);
tx90_shoulder->addChild(m_rot1);
tx90_shoulder->addChild(mygraph);
return tx90_shoulder;
}
SoSeparator* TX90robot::makeRod2()
{
SoSeparator* tx90_arm = new SoSeparator;
m_rot2->axis = SoRotationXYZ::Y;
SoTransform* form2 = new SoTransform;
//form2->translation.setValue(0.05, 0.161, 0.478);
form2->translation.setValue(0.05, 0.161, 0.230);
SoInput inputAxis2;
inputAxis2.openFile("tx90_arm.iv");
SoSeparator* mygraph = SoDB::readAll(&inputAxis2);
mygraph->ref();
tx90_arm->addChild(form2);
tx90_arm->addChild(m_rot2);
tx90_arm->addChild(mygraph);
return tx90_arm;
}
SoSeparator* TX90robot::makeRod3()
{
SoSeparator* tx90_elbow = new SoSeparator;//因为函数要返回soseparator*类型
tx90_elbow->ref();
m_rot3->axis = SoRotationXYZ::Y;
SoTransform* form3 = new SoTransform;
//form3->translation.setValue(0.05, 0.16, 0.903);
form3->translation.setValue(0, 0, 0.425);
SoInput inputAxis3;
inputAxis3.openFile("tx90_elbow.iv");
SoSeparator *mygraph = SoDB::readAll(&inputAxis3);
tx90_elbow->addChild(form3);
tx90_elbow->addChild(m_rot3);
tx90_elbow->addChild(mygraph);
return tx90_elbow;
}
SoSeparator* TX90robot::makeRod4()
{
SoSeparator* tx90_forearm = new SoSeparator;//因为函数要返回soseparator*类型
tx90_forearm->ref();
SoTransform* form4 = new SoTransform;
//form4->translation.setValue(0.05, 0.05, 1.060);//相对基坐标系不对
form4->translation.setValue(0, -0.11, 0.156);//相对上一个零件的坐标系位置
m_rot4->axis = SoRotationXYZ::Z;
SoInput inputAxis4;
inputAxis4.openFile("tx90_forearm.iv");
SoSeparator *mygraph = SoDB::readAll(&inputAxis4);
tx90_forearm->addChild(form4);
tx90_forearm->addChild(m_rot4);
tx90_forearm->addChild(mygraph);
return tx90_forearm;
}
SoSeparator* TX90robot::makeRod5()
{
SoSeparator* tx90_wrist = new SoSeparator;//因为函数要返回soseparator*类型
tx90_wrist->ref();
m_rot5->axis = SoRotationXYZ::Y;
SoTransform* form5 = new SoTransform;
form5->translation.setValue(0, 0, 0.268);
SoInput inputAxis5;
inputAxis5.openFile("tx90_wrist.iv");
SoSeparator *mygraph = SoDB::readAll(&inputAxis5);
tx90_wrist->addChild(form5);
tx90_wrist->addChild(m_rot5);
tx90_wrist->addChild(mygraph);
return tx90_wrist;
}
SoSeparator* TX90robot::makeRod6()
{
SoSeparator* tx90_tool_flange = new SoSeparator;//因为函数要返回soseparator*类型
tx90_tool_flange->ref();
SoTransform* form6 = new SoTransform;
form6->translation.setValue(0, 0, 0.089);
m_rot6->axis = SoRotationXYZ::Z;
SoInput inputAxis6;
inputAxis6.openFile("tx90_tool_flange.iv");
SoSeparator *mygraph = SoDB::readAll(&inputAxis6);
tx90_tool_flange->addChild(form6);
tx90_tool_flange->addChild(m_rot6);
tx90_tool_flange->addChild(mygraph);
return tx90_tool_flange;
}
void TX90robot::makeScene()
{
root = new SoSeparator;
root->ref(); //这个是总结点,要释放下
SoSeparator *robot = new SoSeparator;
SoSeparator *Rod0 = new SoSeparator;
SoSeparator *Rod1 = new SoSeparator;
SoSeparator *Rod2 = new SoSeparator;
SoSeparator *Rod3 = new SoSeparator;
SoSeparator *Rod4 = new SoSeparator;
SoSeparator *Rod5 = new SoSeparator;
SoSeparator *Rod6 = new SoSeparator;
Rod0 = makeRod0();
Rod1 = makeRod1();
Rod1->setName("rod1");
Rod2 = makeRod2();
Rod2->setName("rod2");
Rod3 = makeRod3();
Rod3->setName("rod3");
Rod4 = makeRod4();
Rod4->setName("rod4");
Rod5 = makeRod5();
Rod5->setName("rod5");
Rod6 = makeRod6();
Rod6->setName("rod6");
//设置旋转角度
m_rot1->angle = 0*PI/180;
m_rot2->angle = 90*PI/180;
m_rot3->angle = 45*PI/180;
m_rot4->angle = 0*PI/180;
m_rot5->angle = -90*PI/180;
m_rot6->angle = 0*PI/180;
//按相对坐标 Rod0->addChild(Rod1);表示在ROd0坐标系中组装
robot->addChild(Rod0);
Rod0->addChild(Rod1);
Rod1->addChild(Rod2);
Rod2->addChild(Rod3);
Rod3->addChild(Rod4);
Rod4->addChild(Rod5);
Rod5->addChild(Rod6);
root->addChild(robot);
}
如何在MFC中显示该图形可参考上篇博客。