Phantom omini设备开发流程

最近在忙着做毕业设计,我的毕业设计是做力觉临场感的,所以在力反馈设备Phantom Omini,由于整个设备是国外的国内的资料很少,我是14年拿到这个设备的但是真的是在开发是在16年了,中间有很多事没来得及进行,现在我把我的一个开发流程记录一下,也算是给后面需要使用这个设备的开发人员留下一点资料。

力反馈设备Phantom Omini可以称之为六自由度机械臂,他有六个关节,其中三个关节有电机所以可以提供一个力觉的反馈,它的开发SDK提供了很多的例程,基本上都可以使用,在使用SDK时要注意配置好各个依赖的头文件和.lib库。在正式开发时,我们需要在下面这个Geomagic Touch Setup里面去设置设备的名字,当设置好名字后按下Pairing这个按钮如果出现succussful这个提示说明对设备初始化成功了,在按下Pairing这个按钮一定要不要忘了按设备后面的一个小按钮,只有这样才能初始化成功。

在初始化后我们可以利用设备提供的上位机进行测试。

在这个上位机软件上就可以测试设备末端点的位姿和各个关节的力了。

好了下面我们开始在vs2010里面对设备进行开发,在vs2010里面进行开发我已经默认你已经将vs2010针对Phantom Omini这个设备的库和头文件包含好了。在vs2010里面开发程序我们首先需要了解设备的SDK,整个开发都是基于SDK的,所以熟悉它对开发的进度有很大的帮助,下面的代码的功能是:

1、对两台Phantom Omini设备进行初始

hHD2 = hdInitDevice("PHANToM_05");

hHD1 = hdInitDevice("Default_PHANToM");

2、设置回调函数

整个回调函数会在一个单独的线程中进行执行,在Phantom Omini设备的开发过程中所有的设备状态读取、设备设置都需要在这个线程中执行,都是通过回调函数进行的。

hGravityWell = hdScheduleAsynchronous( SchedulerCallback, 0, HD_MAX_SCHEDULER_PRIORITY);SchedulerCallback就是回调函数。

3、设备使能

hdEnable(HD_FORCE_OUTPUT);

//hdMakeCurrentDevice(hHD1);

hdEnable(HD_FORCE_OUTPUT);

4、开启调度线程

这个线程开启以后除非结束线程,线程会一直执行,并且周期在1000hz、15000hz等周期内循环执行,当然也可以选择只是执行一次,在回调函数中HD_CALLBACK_CONTINUE这个宏可以设置。

hdStartScheduler();

5、打印两个设备的每个关节的关节角然后将关节角写入txt文档中进行保存

  1 /*****************************************************************************
  2
  3 Module Name:
  4
  5   HelloHapticDevice.c
  6
  7 Description:
  8
  9   This application creat the device‘s position and angle,at the moment we just
 10   can use one device.
 11
 12 Auther     : qiuheng
 13
 14 Data       : 2016.12.19
 15
 16 *******************************************************************************/
 17 #ifdef  _WIN64
 18 #pragma warning (disable:4996)
 19 #endif
 20
 21 #include <stdio.h>
 22 #include <assert.h>
 23
 24 #if defined(WIN32)
 25 # include <windows.h>
 26 # include <conio.h>
 27 #else
 28 # include "conio.h"
 29 # include <string.h>
 30 #endif
 31
 32 #include <HD/hd.h>
 33 #include <HDU/hduError.h>
 34 #include <HDU/hduVector.h>
 35
 36 #include<stdio.h>
 37 #include<string.h>
 38
 39 void mainLoop(void);
 40
 41 HDCallbackCode HDCALLBACK gravityWellCallback(void *data);
 42 HDCallbackCode HDCALLBACK gravityWellCallback_1(void *data);
 43 HDCallbackCode HDCALLBACK SchedulerCallback(void *data);
 44 HDCallbackCode HDCALLBACK SchedulerCallback_1(void *data);
 45 /* Data Structure. */
 46 struct Sensable{
 47     hduVector3Dd jointAngles;
 48     hduVector3Dd position;
 49     hduVector3Dd jointTorques;
 50 } Haptic1, Haptic2;
 51
 52 float tau1[3];
 53 float tau2[3];
 54 float tau3[3];
 55 float tau4[3];
 56 double position_[3];
 57 hduVector3Dd joint[3];
 58 HDSchedulerHandle gCallbackHandle = 0;
 59 HHD hHD1;
 60 HHD hHD2;
 61
 62 //Haptic1 is slave robot   ===>Default_PHANToM
 63 //Haptic2 is master robot  ===>PHANToM_05
 64
 65 /*******************************************************************************
 66  Main function.
 67  Initializes the device, starts the schedule, creates a schedule callback
 68  to handle gravity well forces, waits for the user to press a button, exits
 69  the application.
 70 *******************************************************************************/
 71 int main(int argc, char* argv[])
 72 {
 73     HDErrorInfo error;
 74     HDSchedulerHandle   hGravityWell;
 75     HDSchedulerHandle   hGravityWell_1;
 76     //ofstream ofile;               //定义输出文件
 77     FILE *fp1;
 78     FILE *fp2;
 79     FILE *fp3;
 80     FILE *fp4;
 81     int i=0;
 82     int j=0;
 83     /* Initialize the device, must be done before attempting to call any hd
 84        functions. Passing in HD_DEFAULT_DEVICE causes the default device to be
 85        initialized.
 86      */
 87
 88       hHD2 = hdInitDevice("PHANToM_05");
 89         //Sleep(100);
 90         hHD1 = hdInitDevice("Default_PHANToM");
 91
 92     hGravityWell = hdScheduleAsynchronous(
 93             SchedulerCallback, 0, HD_MAX_SCHEDULER_PRIORITY);
 94
 95     hdEnable(HD_FORCE_OUTPUT);
 96     //hdMakeCurrentDevice(hHD1);
 97     hdEnable(HD_FORCE_OUTPUT);
 98
 99     hdStartScheduler();
103     /* Wait until the user presses a key.  Meanwhile, the scheduler
104        runs and applies forces to the device. */
105     //printf("Feel around for the gravity well...\n");
106     //printf("Press any key to quit.\n\n");
107
108     fp1=fopen("D:/毕业设计程序/data/Haptic1_position.txt","a+");
109     fp2=fopen("D:/毕业设计程序/data/Haptic2_position.txt","a+");
110     fp3=fopen("D:/毕业设计程序/data/Haptic1_jointAngles.txt","a+");
111     fp4=fopen("D:/毕业设计程序/data/Haptic2_jointAngles.txt","a+");
112     while (!_kbhit())
113     {
114
115        for(i=0;i<3;i++)
116          {
117              //position_[i]=Haptic1.position[i];
118              printf("Position_1=>%d:%lf\n",i,Haptic1.position[i]);
119              tau3[j]=Haptic1.position[j];
120              fprintf(fp1,"Position_1[%d]:%lf\n",j,tau3[j]);
121              fflush(fp1);
122          }
123
124        for(j=0;j<3;j++)
125          {
126             printf("Angles_1[%d]:%lf\n",j,Haptic1.jointAngles[j]);
127             tau1[j]=Haptic1.jointAngles[j];
128             fprintf(fp3,"Angles_1[%d]:%lf\n",j,tau1[j]);
129          }
130
131        for(i=0;i<3;i++)
132          {
133              //position_[i]=Haptic1.position[i];
134              printf("Position_2=>%d:%lf\n",i,Haptic2.position[i]);
135              tau4[j]=Haptic2.position[j];
136              fprintf(fp2,"Haptic2.position[%d]:%lf\n",j,tau4[j]);
137              fflush(fp2);
138          }
139
140        for(j=0;j<3;j++)
141          {
142             printf("Angles_2[%d]:%lf\n",j,Haptic2.jointAngles[j]);
143             tau2[j]=Haptic2.jointAngles[j];
144             fprintf(fp4,"Angles_2[%d]:%lf\n",j,tau2[j]);
145          }
146
147         /* Periodically check if the gravity well callback has exited. */
148         if (!hdWaitForCompletion(hGravityWell, HD_WAIT_CHECK_STATUS))
149          {
150             fprintf(stderr, "Press any key to quit.\n");
151             getch();
152             break;
153          }
154     }
155
156  // /* For cleanup, unschedule callback and stop the scheduler. */
157     hdStopScheduler();
158     hdUnschedule(hGravityWell);
159     //hdUnschedule(hGravityWell_1);
160     /* Disable the device1. */
161     hdDisableDevice(hHD1);
162     fclose(fp1);
163     fclose(fp2);
164     fclose(fp3);
165     fclose(fp4);
166     /* Disable the device2. */
167     hdDisableDevice(hHD2);
168
169     return 0;
170 }
179 /*=============================================================================*/
180 /* Functions for Phantom =========================================*/
181
182 /******************************************************************
183  * Sets Torque To Haptic.
184  ******************************************************************/
185
186 HDCallbackCode HDCALLBACK SchedulerCallback(void *pUserData)
187 {
188     float a;
189
190     HDErrorInfo error;
191
192     Haptic1.jointTorques[0] = 0;
193     Haptic1.jointTorques[1] = 0;
194     Haptic1.jointTorques[2] = 0;
195
196     Haptic2.jointTorques[0] = 0;
197     Haptic2.jointTorques[1] = 0;
198     Haptic2.jointTorques[2] = 0;
199
200     hdBeginFrame(hHD1);//-------------------------------------------
201
202         //Read Haptic State
203     hdGetDoublev(HD_CURRENT_JOINT_ANGLES, Haptic1.jointAngles);
204     hdGetDoublev(HD_CURRENT_POSITION, Haptic1.position);
205
206
207     hdBeginFrame(hHD2);//-------------------------------------------
208         //Read Haptic State
209     hdGetDoublev(HD_CURRENT_JOINT_ANGLES, Haptic2.jointAngles);
210     hdGetDoublev(HD_CURRENT_POSITION, Haptic2.position);
211
212         //Set Haptic torques (tau)
213     a=1000; //to convert from Nm to mNm
214     Haptic2.jointTorques[0] =250*3.5*(Haptic1.jointAngles[0]-Haptic2.jointAngles[0]);
215     Haptic2.jointTorques[1] =250*3.5*(Haptic1.jointAngles[1]-Haptic2.jointAngles[1]);
216     Haptic2.jointTorques[2] =250*1.5*(Haptic1.jointAngles[2]-Haptic2.jointAngles[2]);
217     hdEnable(HD_FORCE_OUTPUT);
218     hdSetDoublev(HD_CURRENT_JOINT_TORQUE,Haptic2.jointTorques);
219     hdEndFrame(hHD2);//-------------------------------------------------
220
221     hdMakeCurrentDevice(hHD1);
222     //Set Haptic torques (tau)
223     a=1000; //to convert from Nm to mNm
224     Haptic1.jointTorques[0] = -250*3.5*(Haptic1.jointAngles[0]-Haptic2.jointAngles[0]);
225     Haptic1.jointTorques[1] = -250*6*(Haptic1.jointAngles[1]-Haptic2.jointAngles[1]);
226     Haptic1.jointTorques[2] = -250*3.5*(Haptic1.jointAngles[2]-Haptic2.jointAngles[2]);
227
228     hdSetDoublev(HD_CURRENT_JOINT_TORQUE,Haptic1.jointTorques);
229     hdEndFrame(hHD1);//-------------------------------------------------
230
231     return HD_CALLBACK_CONTINUE;
232
233     if (HD_DEVICE_ERROR(error = hdGetError()))
234     {
235         hduPrintError(stderr, &error, "Error while commanding control values");
236         if (hduIsSchedulerError(&error))
237         {
238             return HD_CALLBACK_DONE;
239         }
240     }
241
242     return HD_CALLBACK_CONTINUE;
243 } 
时间: 2024-08-22 21:49:59

Phantom omini设备开发流程的相关文章

【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)

作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42462795 转载请著名出处 相关资源下载 :  -- u-boot 源码 : http://download.csdn.net/detail/han1202012/8342761 -- S3C2440 文档 : http://download.csdn.net/detail/han1202012/8342701 -- S5PV210_iROM_Applicati

微信硬件平台框架说明及接入流程

微信硬件平台框架说明及接入流程1 / 15 硬件平台框架说明及接入流程 V0.5 Tencent Confidential 硬件平台框架说明及接入流程 2 / 15 文档变更日志 部门 微信事业群\开放平台创新部\创新二组 版本 描述 撰写人员 更新日期 V0.1 初稿 jeffqi.genewu 2014/07/8 V0.2 加入Q&A jeffqi.genewu 2014/07/8 V0.3 针对常见问题,增加说明.流程图优化. jeffqi.genewu 2014/07/9 V0.4 添加

mysql数据库之 存储引擎、事务、视图、触发器、存储过程、函数、流程控制

目录 一.存储引擎 1.什么是存储引擎? 2.mysql支持的存储引擎 3. 使用存储引擎 二.事务 三.视图 1.什么是视图 2.为什么要用视图 3.如何用视图 四.触发器 为何要用触发器 创建触发器语法 五.存储过程 六.函数 七.流程控制 八.数据库备份(运维方向) 一.存储引擎 1.什么是存储引擎? mysql中建立的库===>文件夹 库中建立的表===>文件 现实生活中我们用来存储数据的文件有不同的类型,每种文件类型对应各自不同的处理机制:比如处理文本用txt类型,处理表格用exce

#24 centos6(RHEL)系列操作系统的启动流程、与命令chkconfig、grub的使用

所有由rc脚本关闭或启动的链接文件的原文件都存在于/etc/rc.d/init.d,系统为了方便使用,为此目录创建了链接/etc/init.d 所有/etc/inid.d(/etc/rc.d/init.d)目录中的脚本执行方式: # /etc/init.d/srv_script {start|stop|restart|status} # service srv_script {start|stop|restart|status} chkconfig命令: chkconfig - updates

游戏测试经历的流程及发版本注意的问题(或许有遗漏)

一.测试流程: 1.测试人员需要参与需求会议,了解需求,如有必要,提出疑问点,产品修改正 2.需求确定后,编辑测试用例或者测试功能点 3.开发提交完毕后,执行测试用例(要求开发出电脑版,节约前期打包,安装包的时间) 4.发现bug,提交bug到禅道,并通知相关人员 5.开发组修正bug,禅道指派给测试人员,表明已修复 6.对已修正的bug,进行回归测试 7.修正完毕的bug在禅道上置为关闭 8.待电脑版功能验证完毕后,进行手机包测试 9.整体测试完毕,可以发布包 补充: 1.中途有修改需求,也需

汇编语言入门:流程控制

流程控制:顺序,分支,循环 程序计数器PC中存储当前执行的程序在EM中的位置 汇编里面,用比较.跳转实现流程控制. 1.顺序:PC+1(不一定加一,看指令长度) 2.分支循环,直接赋给PC值,执行指定地址的程序 有时候需要程序有一定的流程控制能力,它不是老老实实按照顺序来执行的,中间可能会跳过一些代码 修改PC值,不可用MOV指令,PC是特殊的寄存器,特殊对待,跳转指令修改其值. 跳转指令: 1 ja 大于时跳转 2 jae 大于等于 3 jb 小于 4 jbe 小于等于 5 je 相等 6 j

1.2软件生命周期&amp;测试流程

软件的生命周期 可行性分析-需求分析-软件设计-软件编码-软件测试-软件维护 1.可行性分析 主要确定软件开发的目的和可行性(PM) 2.需求分析 对软件的功能进行详细的分析(PM),输出需求规格说明书(原型图) 3.软件设计(DEV) 把需求分析得到的结果转换为软件结构和数据结构,形成系统架构 概要设计:搭建架构.模块功能.接口连接和数据传输 详细设计:模块深入分析,对各模块组合进行分析,伪代码   包含数据库设计说明 4.软件编码(DEV) 可运行的程序代码 5.软件测试 5.1.单元测试(

敏捷流程

流程简介 第一步:找出完成产品需要做的事情--Product Backlog 第二步:决定当前的冲刺需要解决的事情--Sprint Backlog 第三步:冲刺 第四步:得到软件的一个增量版本,发布给用户 敏捷流程的问题和解法 第一步:在计划中体现依赖关系 第二步:技术能力和交流能力 第三步:定义好任务 第四步:得到一个增量的软件发布 敏捷的团队: 自主管理 自我组织 多功能型 敏捷流程的经验教训: 敏捷宣言表明的是一些优先级 Scrum Master不是一个官,而是一个没有执行权力的沟通者 一

车牌OCR识别的流程,手机车牌识别

车牌的OCR识别的流程如下: 手机车牌识别背景 随着人们生活水平的提高,汽车方面的业务量也日益暴涨,加上如今"互联网+"的提出,智能终端(智能手机及平板电脑)及移动通信(4G)发展迅速,人们用手机的频率比用电脑的多,加上手机小巧轻便,成为生活中必要的工作及社交工具,可以预见未来几年60%以上的业务将会逐渐转移到智能终端系统上来.伴随着移动端APP的火爆应用,易泊将原来应用在电脑端的车牌识别技术转移到了移动端,手机车牌识别更加灵活,方便,为人们的应用解决了很多实际困难. 手机车牌识别描述