虚拟 机器人 系统 仿真 初步 第四章 机器人模型和交互控制
4.1机器人机械臂结构
因有关机器人细节有泄密之嫌,特删除之。文中图片所示为kr6模型,模型具体文件来自老外网站。
4.3 定义机器人几何形体的VRML文件
#VRML V2.0 utf8
DEF joint0 Transform {scale 0.01 0.01 0.01 rotation 1 0 0 1.5708
children [
Inline{url "arm0.wrl"}
#以包含基座形体几何信息的文件arm0.wrl作为joint0的子节点
Transform{translation 0 0 -675 rotation 1 0 0 1.5708
#根据连杆参数几何变换下一关节
children [
DEF joint1 Transform{
Children[
Inline{url "arm1.wrl"}
#以包含形体几何信息的文件arm1.wrl作为joint1的子节点
Transform{
translation 300 0 0
rotation 1 0 0 1.5708
children[
#如此循环至末端执行器
……
]}
]}
]}
]}
4.4 用Java封装与机器人有关的MyRobot类
该类主要功能是根据文件名装载wrl文件定义的几何形体信息到虚拟场景中,并且用外部程序接口的方式获得其中控制关节参数的J3DTransform对象,并且根据外部配置文件配置各关节的活动范围。
class MyRobot{
BranchGroup robotBG; // 用于返回给Java3D的几何节点
private J3DTransform joints[]; //关节对象
private int DOF =0; //自由度
private float minValue[],maxValue[];
public MyRobot(String filename,int N){
int flag = VRML97Loader.LOAD_ALL;
VRML97Loader loader = new VRML97Loader(flag);
……
Scene scene = null;
try {
scene = loader.load(file);
/*用VRML97Loader类加载文件名file指定的机器人信息的文件*/
} catch(Exception e) {
System.out.println("Exception loading URL:" + e);
e.printStackTrace();
System.exit(0);
}
robotBG = new BranchGroup();
if (scene != null) {
// get the scene group
robotBG = scene.getSceneGroup(); //返回场景数据
……
}
VRMLScene vrmlscene = loader.getVRMLScene();
DOF=N;
joints = new J3DTransform[N];
names = new String[N];
for(int i=0; i
names[i] = "joint"+(i+1); joints[i]= (J3DTransform)vrmlscene.getDEFNodes().get(names[i]);/*一个要害的方法,使用Java的反馈技术,得到前面wrl文件中用DEF定义的关节对象,机器人控制时改变这个其参数就可以达到控制效果*/ } …… /*以下为MyRobot类的成员函数,对应可能的对机器人模型的操作,主要是D-H参数的获取和设置*/ protected boolean setRobot(float [] param){ } protected float[] getRobot(){ } protected J3DTransform[] getJoints(){ return joints; } protected int getDOF(){ return DOF; } }说明有论文描述过用Java3D中的TransformGroup节点来组织机器人模型,而我通过java的 反馈技术得到内存中的关节对象,并通过EAI方式控制机器人,这样使程序变得简洁、耦合度降低,从而可以不破坏信息相对集中的原则。前者使用的方式较为原始和直观,后者则需要对VRML和Java较深入的理解。在此,因为非凡原因无法获得研究对象的详实数据,所以使用了一个替代的机器人模型kr6.wrl. 4.5 交互控制对于虚拟仿真而言,交互是必不可少的,这也是仿真区别于动画的一个重要特征。我定义了键盘交互和控件交互两种,实际可以轻易做到程序交互和鼠标交互。4.5.1 Java3D行为类BehaviorBehavior类是Java3D中一个处理动态交互的类,包括JAVA代码和状态变量。Behavior叶结点对象包含了一个行为调度临界值和两个方法, 行为调度临界值中定义了一个非凡的值以便安排Behavior对象结点的调度执行。当ViewPlatform的活动值达到调度临界值时,Behavior对象结点就处于活动状态,也只有活动的Behavior对象才能接收激发参数。两个方法:一个是当该结点进入活动状态时执行的初始化方法initialize(),另一个是JAVA3D动作调度程序在特定时刻所调用的刺激响应的方法processStimulus()。Initialization()方法可以设置Behavior对象的内在状态和指定唤醒条件,当Behavior对象所在的BranchGroup对象结点附加到VirsualUniverse对象结点时,JAVA3D程序将调用Behavior对象的初始化方法。Initialize方法答应一个动作结点对象初始化它的内部状态信息,并指定初始被唤醒的条件。JAVA3D在动作结点所在的BranchGroup结点被添加到虚拟宇宙之后调用动作结点的初始化代码,该调用并不是产生一个新的线程,因此,为了让JAVA3D继续把握控制权,初始化方法中不答应出现无限循环代码,也就是说必须立即返回,而且,必须设定至少一个以上的唤醒条件,否则,刺激影响方法永远不会被执行到。processSitmulus()方法接收和处理Behavior对象执行的消息。ProcessStimulus处理该运动结点在运行中所接收到的运行消息。当一个视平台的作用区域同一个动作结点的感应区域产生交集,并且动作结点的唤醒准则的设置是合理的,则JAVA3D的动作调度程序就会调用该动作结点的刺激响应方法。刺激响应方法先从例举结构(Enumeration)提取出不同的刺激完成指定的计算和动作, 包括操纵场景中的物体的运动,改变内部状态信息,以及让JAVA3D去唤醒其他的动作结点对象,之后设定自身的新的唤醒条件,并返回。当然,对其自身和其他对象的操作必须建立在相关对象的权限(Capabilities)已被设定的基础上。按下列步骤可以在虚拟世界中正确建立一个行为(Behavior)节点:1.初始化构造或者继续一个Behavior节点并注册唤醒条件 WakeUpCondition;2.Java3D进入它的行为处理循环;3.Java3D检测当前Behavior节点的唤醒条件是否成立;4.由Java3D调用唤醒响应方法;5.Behavior节点执行相应响应代码;6.Behavior节点设置下一个唤醒条件;7.Java3D行为处理循环处理下一个Behavior节点。 4.5.2 定义键盘交互行为类键盘行为类主要是通过键盘按键来控制机器人对象,也是虚拟仿真中最常见的交互方式,实现的要害是行为类的定义和按键检测。(详见keyRobotBehaviour.java)//开始自定义一个键盘行为类keyRobotBehaviourpublic class keyRobotBehaviour extends Behavior {……//构造函数Public keyRobotBehaviour(BoundingSphere theBounds,MyRobot myRobot){……}//初始化方法,注册唤醒条件为击键事件public void initialize() { theCriterion = new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED); wakeupOn(theCriterion); }//定义刺激响应方法public void processStimulus(Enumeration criteria) { //进入行为处理循环 while (criteria.hasMoreElements()) { …… //检测按键动作 switch(keyPressed){ case KeyEvent.VK_1 : //按数字键1的响应行为/*用if(keyevent.isShiftDown())判定是否同时按下组合键,则响应不同的行为*/ break; case KeyEvent.VK_2 : …… default break;}}}//注册下一个唤醒行为wakeupOn(theCriterion);}}说明:此处以MyRobot类的句柄作为参数,按键响应代码中利用这一句柄访问机器人模型类的相关参数,从而控制机器人模型。其中因为机器人关节节点来自于vrml场景,因此不能使用Java3D中的节点控制关节参数,此处用到了xj3d中的J3DTransform节点,由其setRotation方法来改变关节旋转参数。程序中节点类型及其行为可以参考官方文档,在文档也可以使用Java虚拟机中的调试台命令了解其成员函数,这一点有一定的程序技巧。 4.5.3 自定义GUI控件交互控制GUI控件――GUI界面上的按钮等,该控制不同于行为节点的控制,需要将响应部分的代码定义到控件行为中,而不是Java3D的行为节点中。同样也必须传递控制对象MyRobot类的句柄给控件,而且编程中发现所要使用的某些控件不能达到控制要求,因此我自定义了一个控件类MyDevice,这样可以将特定机器人关节和该控件对应起来。如图4-4:
图4-4 自定义的GUI控件其中响应滑动条事件的代码如下:slider.addChangeListener(new ChangeListener(){ public void stateChanged(ChangeEvent event){ curInt = ((JSlider)event.getSource()).getValue(); curValue = minValue +curInt*(maxValue-minValue)/100; valueText.setText(""+formatter.format(curValue)); if(AS){ param[index]=curValue; myRobot.setRobot(param); } }});详见程序清单中JointControl.java. 4.5.4 实现离线编程器在此基础上设计了一个解释器,可以使用机器人关节级语言来控制机器人的关节参数,也可以在此基础上实现更为复杂的语言解释器。其原理与以上大体一致,主要也是通过MyRobot类的句柄访问控制对象。由此可见设计MyRobot类可以让系统的模块化更为清楚,也体现了MVC的系统构架对机器人仿真是合适的。 4.6 运动学、动力学引擎 与 Robot.xml该模块属于机器人控制领域的问题,我并没有实现该模块功能,仅仅为方便今后集成该模块提供了接口,主要工作是集成了对Robot.xml文档的支持。XML是一种非常有用的软件工程技术,它的设计原则就是以简洁的规则提供最好的扩展性。作为一种文档编码规范,它通过定义文档类型(Document Type Define)来产生结构化良好的文档。如今,已经有成功用于数学表达的Math ML ,化学领域分子式、方程描述的Chemical ML,等等。我通过了解国外同类型项目,发现已有组织开始制定机器人应用领域的文档类型,在机器人仿真中应用该技术,其主要功能是:首先xml是结构化良好的文档,比一般用txt定义的配置文件更为科学,此外可以用dtd来规范机器人参数的描述,对于机器人产品的市场交流也大有裨益。如下,所有机器人产品文件在文件开头指定用于文档结构分析的robot.dtd文档,则产品描述文件则遵从dtd中定义的表达规则。 设计意图来源于对国际上一个开源的软件项目Orocos( Open Robot Control Software/ Open Realtime Control Services,官方站点http://www.orocos.org)的粗略理解,如图,仿真系统可以从robot.xml中提取机器人对象的动力学的参数、仿真环境设置参数等信息。图4-5为Orocos 与xml 的关系。 图4-6为部分系统配置文件的细节。
图4-5 Orocos 与xml 的关系
图4-6 动力引擎xml配置文件 目前系统已集成了xml文档的读取和浏览器,须进一步根据系统功能定义解析器。在Java程序中处理Xml文档有两种方式:DOM和SAX,前者是文档对象模型,后者是XML的简单API分析器,后者可以在程序中较为方便的定义文档的解析器。具体地,解析开始之前,需要向XMLReader注册一个ContentHandler,也就是相当于一个事件监听器,在ContentHandler中定义了很多方法,比如startDocument(),它定制了当在解析过程中,碰到文档开始时应该处理的事情。当XMLReader读到合适的内容,就会抛出相应的事件,并把这个事件的处理权代理给ContentHandler,调用其相应的方法进行响应。
4-7 XML解析器
【上一页】
【下一页】
本文地址:http://www.cg3000.com/html/cgTutorials/VirtualReality/Java3D/20071205/jiqirenxunifangzhenxitongchubuyanjiu_si__69352.shtml