最近在忙着做毕业设计,我的毕业设计是做力觉临场感的,所以在力反馈设备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文档中进行保存

 /*****************************************************************************
 Module Name:

   HelloHapticDevice.c

 Description: 

   This application creat the device's position and angle,at the moment we just
can use one device. Auther : qiuheng Data : 2016.12.19 *******************************************************************************/
#ifdef _WIN64
#pragma warning (disable:4996)
#endif #include <stdio.h>
#include <assert.h> #if defined(WIN32)
# include <windows.h>
# include <conio.h>
#else
# include "conio.h"
# include <string.h>
#endif #include <HD/hd.h>
#include <HDU/hduError.h>
#include <HDU/hduVector.h> #include<stdio.h>
#include<string.h> void mainLoop(void); HDCallbackCode HDCALLBACK gravityWellCallback(void *data);
HDCallbackCode HDCALLBACK gravityWellCallback_1(void *data);
HDCallbackCode HDCALLBACK SchedulerCallback(void *data);
HDCallbackCode HDCALLBACK SchedulerCallback_1(void *data);
/* Data Structure. */
struct Sensable{
hduVector3Dd jointAngles;
hduVector3Dd position;
hduVector3Dd jointTorques;
} Haptic1, Haptic2; float tau1[];
float tau2[];
float tau3[];
float tau4[];
double position_[];
hduVector3Dd joint[];
HDSchedulerHandle gCallbackHandle = ;
HHD hHD1;
HHD hHD2; //Haptic1 is slave robot ===>Default_PHANToM
//Haptic2 is master robot ===>PHANToM_05 /*******************************************************************************
Main function.
Initializes the device, starts the schedule, creates a schedule callback
to handle gravity well forces, waits for the user to press a button, exits
the application.
*******************************************************************************/
int main(int argc, char* argv[])
{
HDErrorInfo error;
HDSchedulerHandle hGravityWell;
HDSchedulerHandle hGravityWell_1;
//ofstream ofile; //定义输出文件
FILE *fp1;
FILE *fp2;
FILE *fp3;
FILE *fp4;
int i=;
int j=;
/* Initialize the device, must be done before attempting to call any hd
functions. Passing in HD_DEFAULT_DEVICE causes the default device to be
initialized.
*/ hHD2 = hdInitDevice("PHANToM_05");
//Sleep(100);
hHD1 = hdInitDevice("Default_PHANToM"); hGravityWell = hdScheduleAsynchronous(
SchedulerCallback, , HD_MAX_SCHEDULER_PRIORITY); hdEnable(HD_FORCE_OUTPUT);
//hdMakeCurrentDevice(hHD1);
hdEnable(HD_FORCE_OUTPUT); hdStartScheduler();
/* Wait until the user presses a key. Meanwhile, the scheduler
runs and applies forces to the device. */
//printf("Feel around for the gravity well...\n");
//printf("Press any key to quit.\n\n"); fp1=fopen("D:/毕业设计程序/data/Haptic1_position.txt","a+");
fp2=fopen("D:/毕业设计程序/data/Haptic2_position.txt","a+");
fp3=fopen("D:/毕业设计程序/data/Haptic1_jointAngles.txt","a+");
fp4=fopen("D:/毕业设计程序/data/Haptic2_jointAngles.txt","a+");
while (!_kbhit())
{ for(i=;i<;i++)
{
//position_[i]=Haptic1.position[i];
printf("Position_1=>%d:%lf\n",i,Haptic1.position[i]);
tau3[j]=Haptic1.position[j];
fprintf(fp1,"Position_1[%d]:%lf\n",j,tau3[j]);
fflush(fp1);
} for(j=;j<;j++)
{
printf("Angles_1[%d]:%lf\n",j,Haptic1.jointAngles[j]);
tau1[j]=Haptic1.jointAngles[j];
fprintf(fp3,"Angles_1[%d]:%lf\n",j,tau1[j]);
} for(i=;i<;i++)
{
//position_[i]=Haptic1.position[i];
printf("Position_2=>%d:%lf\n",i,Haptic2.position[i]);
tau4[j]=Haptic2.position[j];
fprintf(fp2,"Haptic2.position[%d]:%lf\n",j,tau4[j]);
fflush(fp2);
} for(j=;j<;j++)
{
printf("Angles_2[%d]:%lf\n",j,Haptic2.jointAngles[j]);
tau2[j]=Haptic2.jointAngles[j];
fprintf(fp4,"Angles_2[%d]:%lf\n",j,tau2[j]);
} /* Periodically check if the gravity well callback has exited. */
if (!hdWaitForCompletion(hGravityWell, HD_WAIT_CHECK_STATUS))
{
fprintf(stderr, "Press any key to quit.\n");
getch();
break;
}
} // /* For cleanup, unschedule callback and stop the scheduler. */
hdStopScheduler();
hdUnschedule(hGravityWell);
//hdUnschedule(hGravityWell_1);
/* Disable the device1. */
hdDisableDevice(hHD1);
fclose(fp1);
fclose(fp2);
fclose(fp3);
fclose(fp4);
/* Disable the device2. */
hdDisableDevice(hHD2); return ;
}
/*=============================================================================*/
/* Functions for Phantom =========================================*/ /******************************************************************
* Sets Torque To Haptic.
******************************************************************/ HDCallbackCode HDCALLBACK SchedulerCallback(void *pUserData)
{
float a; HDErrorInfo error; Haptic1.jointTorques[] = ;
Haptic1.jointTorques[] = ;
Haptic1.jointTorques[] = ; Haptic2.jointTorques[] = ;
Haptic2.jointTorques[] = ;
Haptic2.jointTorques[] = ; hdBeginFrame(hHD1);//------------------------------------------- //Read Haptic State
hdGetDoublev(HD_CURRENT_JOINT_ANGLES, Haptic1.jointAngles);
hdGetDoublev(HD_CURRENT_POSITION, Haptic1.position); hdBeginFrame(hHD2);//-------------------------------------------
//Read Haptic State
hdGetDoublev(HD_CURRENT_JOINT_ANGLES, Haptic2.jointAngles);
hdGetDoublev(HD_CURRENT_POSITION, Haptic2.position); //Set Haptic torques (tau)
a=; //to convert from Nm to mNm
Haptic2.jointTorques[] =*3.5*(Haptic1.jointAngles[]-Haptic2.jointAngles[]);
Haptic2.jointTorques[] =*3.5*(Haptic1.jointAngles[]-Haptic2.jointAngles[]);
Haptic2.jointTorques[] =*1.5*(Haptic1.jointAngles[]-Haptic2.jointAngles[]);
hdEnable(HD_FORCE_OUTPUT);
hdSetDoublev(HD_CURRENT_JOINT_TORQUE,Haptic2.jointTorques);
hdEndFrame(hHD2);//------------------------------------------------- hdMakeCurrentDevice(hHD1);
//Set Haptic torques (tau)
a=; //to convert from Nm to mNm
Haptic1.jointTorques[] = -*3.5*(Haptic1.jointAngles[]-Haptic2.jointAngles[]);
Haptic1.jointTorques[] = -**(Haptic1.jointAngles[]-Haptic2.jointAngles[]);
Haptic1.jointTorques[] = -*3.5*(Haptic1.jointAngles[]-Haptic2.jointAngles[]); hdSetDoublev(HD_CURRENT_JOINT_TORQUE,Haptic1.jointTorques);
hdEndFrame(hHD1);//------------------------------------------------- return HD_CALLBACK_CONTINUE; if (HD_DEVICE_ERROR(error = hdGetError()))
{
hduPrintError(stderr, &error, "Error while commanding control values");
if (hduIsSchedulerError(&error))
{
return HD_CALLBACK_DONE;
}
} return HD_CALLBACK_CONTINUE;
}

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

  1. yumiot的发展历程。

    yumiot,大家可能没有听说过,不过作为物联网行业一颗冉冉升起的新星,大家有必要加深这一方面的了解.我先简单介绍一下这个企业.物联网,作为国家大力扶持的行业,相信大家身边也有很多这样的物联网企业.不 ...

  2. linux驱动之一语点破天机

    <const 关键字> 在嵌入式系开发中,const关键字就是“只读”的意思   <为什么要ARM需要进行C语言环境的初始化> 在汇编情况下,指令的跳转,保护现场需要保存的数据 ...

  3. 鸿蒙HarmonyOS应用开发落地实践,Harmony Go 技术沙龙落地北京

    12月26日,华为消费者BG软件部开源中心与51CTO Harmony OS技术社区携手,共同主办了主题为"Harmony OS 应用开发落地实践"的 Harmony Go 技术沙 ...

  4. Android项目实战(二十六):蓝牙连接硬件设备开发规范流程

    前言: 最近接触蓝牙开发,主要是通过蓝牙连接获取传感器硬件设备的数据,并进行处理. 网上学习一番,现整理出一套比较标准的 操作流程代码. 如果大家看得懂,将来只需要改下 硬件设备的MAC码 和 改下对 ...

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

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42462795 转载请著名出处 相关资源下载 :  -- u-boo ...

  6. mysql-视图、触发器、事务、存储过程、流程控制

    目录 视图 触发器 事务 存储过程 流程控制 一.视图 视图是由查询结果构成的一张虚拟表,和真实的表一样,带有名称的列和行数据 强调:视图是永久存储的,但是视图存储的不是数据,只是一条sql语句 视图 ...

  7. Android内存泄漏的检测流程、捕捉以及分析

    https://blog.csdn.net/qq_20280683/article/details/77964208 Android内存泄漏的检测流程.捕捉以及分析 简述: 一个APP的性能,重度关乎 ...

  8. (7.0 version)当销售单中包含service或phantom类型的产品时,销售单不能完成的原因分析及解决方案

    首先说一下service类型的产品,由于该类型的产品不需要发货,所以当在销售订单确认了后,销售单直接变成了等待开票的状态,但当开票的流程结束后,订单却还是停在销售单的状态上,该问题的解决方案是安装Ta ...

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

    目录 一.存储引擎 1.什么是存储引擎? 2.mysql支持的存储引擎 3. 使用存储引擎 二.事务 三.视图 1.什么是视图 2.为什么要用视图 3.如何用视图 四.触发器 为何要用触发器 创建触发 ...

随机推荐

  1. Ubuntu 14.04 – How to install xrdp in Ubuntu 14.04

    http://c-nergy.be/blog/?p=5305 Hello World, Ubuntu 14.04 has been released on April 17th 2014 and we ...

  2. Spring Controller 获取请求参数的几种方法

    1.直接把表单的参数写在Controller相应的方法的形参中,适用于get方式提交,不适用于post方式提交.若"Content-Type"="application/ ...

  3. JS兼容getElementsByClassName

    getElementsByClassName是通过class来获取DOM,但是IE8及以下不能兼容.这里做了一下兼容性. HTML: <div class="pox"> ...

  4. POJ C++程序设计 编程题#3 编程作业—运算符重载

    编程题 #3 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 写一个二维数组 ...

  5. http://www.shanghaihaocong.com-WORDPRESS开发的企业主题站

    wordpress是世界上使用最多的php开源博客系统,功能强大,而且拥有众多的插件,可扩展性强. 最近,我也用它做了一个企业网站,欢迎浏览:http://www.shanghaihaocong.co ...

  6. js一些稀奇古怪的写法-带你装逼带你飞

    //定时器的第三个参数 setInterval(function(str1,str2,num){ alert(str1+str2+num) },1000,'参数1','还可以有很多参数,不同的类型.. ...

  7. c语言学习的第四天2

    上图显示了float和double的精度,精度:就是指数值的精确程度,浮点类型可表示的数值范围很大,但只有几位是精确的,可以通过小 数所占的位数来获取,float小数部分最多能有7位有效数字,但绝对能 ...

  8. php根据身份证号码计算年龄

    代码如下 复制代码 <?php function getAgeByID($id){         //过了这年的生日才算多了1周岁         if(empty($id)) return ...

  9. U盘启动

    2014.4.3修改 其实用U盘制作系统也可以下载一个软碟通UltraISO,就可以很方便的制作. ----以前的版本 用U盘装系统,很方便快捷,下面这个网站介绍的比较详细,于是自己整理了一下,作为收 ...

  10. SQL Server 锁表、查询被锁表、解锁相关语句

    SQL Server 锁表.查询被锁表.解锁相关语句,供参考. --锁表(其它事务不能读.更新.删除) BEGIN TRAN SELECT * FROM <表名> WITH(TABLOCK ...