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.如何用视图 四.触发器 为何要用触发器 创建触发 ...
随机推荐
- php中实现17种正则表达式
php中实现17种正则表达式 该教程来自:php教程网:http://php.662p.com "^\d+[ DISCUZ_CODE_1 ]quot; //非负整数(正整数 + 0) &qu ...
- nginx负载均衡配置一(反向代理)
一.前提 1:系统linux(centos) 2:nginx代理服务器(web:192.168.1.10 proxy.abc.com) 3:nginx后台服务器(web1:192.168.1.11 ...
- Linux安装VritualBox实现虚拟机win2003端口映射 支持远程
1. 使用VNC登录到Linux系统 2. 安装VritualBox 找到VritualBox的软件包 这里的是run格式的 可以直接在终端运行 需要几分钟时间 3.VritualBox新建虚拟机 ...
- [leetcode]_Minimum Depth of Binary Tree
第五道树题,10分钟之内一遍AC.做树题越来越有feel~ 题目:求一棵树从root结点到叶子结点的最短路径. 思路:仍然是递归.如果一个结点的左右子树任意一边为Null,该子树的minDepth应为 ...
- jquery easyui combobox
$("#select_Dic").combobox({ url: "http://www.cnblogs.com/Ajax/ ...
- kvm介绍
KVM(Kernel-Based Virtual Machines)是一个基于Linux内核的虚拟化技术, 可以直接将Linux内核转换为Hypervisor(系统管理程 序)从而使得Linux内核能 ...
- java初探native
最近碰见一个java中一个native关键字,不知道是干什么的,如下: public native String FileName(String strURL); static{ ...
- svn的使用!!!
1.SVN:subversion(子级源代码版本控制管理软件) 2.SVN的作用 (1)避免开发同一项目不会出现代码覆盖. (2)同一文件可以创建许多不同的版本,并可以随时查看不同版本的内容. (3) ...
- 【转】代码编辑器(二)-SynEdit
在我去年的时候我就有这个了,而且这是我第二个第三方的控件(第一个是DevExpress),这个是专门做代码编辑器的.安装方法:点我. 安装成功了之后,会在Tool Palette看到两个:SynEdi ...
- selenium+python登录登出百度,等待页面加载,鼠标定位
#coding:gbk from selenium import webdriver from selenium.webdriver.common.keys import Keys from sele ...