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文档中进行保存
/*****************************************************************************
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设备开发流程的更多相关文章
- yumiot的发展历程。
yumiot,大家可能没有听说过,不过作为物联网行业一颗冉冉升起的新星,大家有必要加深这一方面的了解.我先简单介绍一下这个企业.物联网,作为国家大力扶持的行业,相信大家身边也有很多这样的物联网企业.不 ...
- linux驱动之一语点破天机
<const 关键字> 在嵌入式系开发中,const关键字就是“只读”的意思 <为什么要ARM需要进行C语言环境的初始化> 在汇编情况下,指令的跳转,保护现场需要保存的数据 ...
- 鸿蒙HarmonyOS应用开发落地实践,Harmony Go 技术沙龙落地北京
12月26日,华为消费者BG软件部开源中心与51CTO Harmony OS技术社区携手,共同主办了主题为"Harmony OS 应用开发落地实践"的 Harmony Go 技术沙 ...
- Android项目实战(二十六):蓝牙连接硬件设备开发规范流程
前言: 最近接触蓝牙开发,主要是通过蓝牙连接获取传感器硬件设备的数据,并进行处理. 网上学习一番,现整理出一套比较标准的 操作流程代码. 如果大家看得懂,将来只需要改下 硬件设备的MAC码 和 改下对 ...
- 【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)
作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42462795 转载请著名出处 相关资源下载 : -- u-boo ...
- mysql-视图、触发器、事务、存储过程、流程控制
目录 视图 触发器 事务 存储过程 流程控制 一.视图 视图是由查询结果构成的一张虚拟表,和真实的表一样,带有名称的列和行数据 强调:视图是永久存储的,但是视图存储的不是数据,只是一条sql语句 视图 ...
- Android内存泄漏的检测流程、捕捉以及分析
https://blog.csdn.net/qq_20280683/article/details/77964208 Android内存泄漏的检测流程.捕捉以及分析 简述: 一个APP的性能,重度关乎 ...
- (7.0 version)当销售单中包含service或phantom类型的产品时,销售单不能完成的原因分析及解决方案
首先说一下service类型的产品,由于该类型的产品不需要发货,所以当在销售订单确认了后,销售单直接变成了等待开票的状态,但当开票的流程结束后,订单却还是停在销售单的状态上,该问题的解决方案是安装Ta ...
- mysql数据库之 存储引擎、事务、视图、触发器、存储过程、函数、流程控制、数据库备份
目录 一.存储引擎 1.什么是存储引擎? 2.mysql支持的存储引擎 3. 使用存储引擎 二.事务 三.视图 1.什么是视图 2.为什么要用视图 3.如何用视图 四.触发器 为何要用触发器 创建触发 ...
随机推荐
- 022 ARM寄存器详解
R13:堆栈指针寄存器 SP R14:链接寄存器 LR R15:程序计数器 PC指针 CPSR:当前程序状态寄存器 SPSR:备份程序状态寄存器
- MySQL深入利用Ameoba实现读写分离
3 ameoba安装配置 3.1 安装配置JDK [root@stu15 ~]# rpm -ivh jdk-7u67-linux-x64.rpm [root@stu15 ~]# cd /usr/j ...
- POJ C++程序设计 编程作业—类和对象 编程题 #2
编程题 #2 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 下面程序的输出 ...
- MapReduce框架Partitioner分区方法
前言:对于二次排序相信大家也是似懂非懂,我也是一样,对其中的很多方法都不理解诶,所有只有暂时放在一边,当你接触到其他的函数,你知道的越多时你对二次排序的理解也就更深入了,同时建议大家对wordcoun ...
- MySQL的相关概念介绍
MySQL 为关系型数据库(Relational Database Management System), 这种所谓的"关系型"可以理解为"表格"的概念, 一个 ...
- 关于commons-fileupload组件上传文件中文名乱码问题
java web开发,常用到的文件上传功能,常用的commons-fileupload和commons-io两个jar包.关于如何使用这两个jar来完成文件上传的功能,这里不做详解.使用commons ...
- 新浪博客如何显示高亮代码,DIY
新浪博客对代码的支持功能不尽完美,或者说一点都不好,可是对于一个追求完美的技术痴而言,代码不能够完美的显示,心里总有那么一些不爽,那么如何在新浪中显示那些带颜色的代码呢?经过探究,可以如下设置: ...
- js代码优化
1.减少Jquery使用 处理dom遍历和复杂的脚本场景时,jquery可能有很大的帮助,不过在处理简单的.直截了当的代码场景就会迟缓.尽可能的避免jquery对象创建,尤其在循环中. 2.优化循环 ...
- 访问svc 文件,编译器错误消息: CS0016,未能写入输出文件
编译错误 说明: 在编译向该请求提供服务所需资源的过程中出现错误.请检查下列特定错误详细信息并适当地修改源代码. 编译器错误消息: CS0016: 未 ...
- MongoDB工具简要说明
[mongodb@hadoop1 bin]$ pwd /usr/local/mongodb/bin [mongodb@hadoop1 bin]$ ls -l total 207696 -rwxr-xr ...