最近在忙着做毕业设计,我的毕业设计是做力觉临场感的,所以在力反馈设备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. 最新仿梦芭莎免费ecshop模板

    最新仿梦芭莎免费ecshop模板,该源码很真实地模仿了我们比较熟悉的梦芭莎购物网站的,我们知道该网站商城很受大家的喜欢的,而且界面也很漂亮的,希望能够帮到大家的学习. <ignore_js_op ...

  2. 关于使用SVN update时出现:E155004错误

    今天早上到公司开了电脑,准备update下SVN的代码,但是在update时出现svn: E155004: Working copy 'E:\XX' locked  错误,乍眼一看以为是什么配置出错, ...

  3. 对C语言中va_list,va_start,va_arg和va_end的一点理解

    这几个函数和变量是针对可变参数函数的,什么是可变参数函数呢,最经典的莫过于printf和scanf,这两个函数的声明如下: int printf(const char *format, ...); i ...

  4. Hive[2] 基础介绍

    2.3 Hive 内部介绍: P44 $HIVE_HOME/lib 下的 jar 文件是具体的功能部分:(CLI模块) 其它组件,Thrift 服务,可以远程访问其他进程功能:也有使用 JDBC 和 ...

  5. The given path's format is not supported.

    问题 编程以来今本没有使用input[type=file]这个控件过,今天突然使用尽然报错了,在本地chrome,firefox等其他的浏览器都是好的,唯独ie报错了.在服务器的时候,尽然chrome ...

  6. ISBN和标准编码关系以及概念

    <中国标准书号>(China standard Book Number)是1986年由国家标准局批准颁发的一项国家标准(GB5795-86).该标准是在采用国际标准LSO2108——国际标 ...

  7. C#winform在textbox插入内容换行

    要让一个TextBox显示多行文本就得把它的Multiline属性设置为true,可是如果你是要把TextBox的Text属性设置多行文本时可能会遇到点麻烦,也许你会想到直接加一个换行符"\ ...

  8. 利用crontab自动更新SVN代码

    shell.sh#!/bin/sh source ~/.bash_profile LANG=en_US.UTF- cd /opt/web/hzcms/ svn up >> /opt/web ...

  9. linux安装至少有哪两个分区,各自作用是什么?

    1.至少有/代表根分区,/swap代表的意思是交换分区. 2.swap相当于缓存的作用:

  10. 【转】MessageBox

    MessageBox对话框是比较常用的一个信息对话框,其不仅能够定义显示的信息内容.信息提示图标,而且可以定义按钮组合及对话框的标题,是一个功能齐全的信息对话框. 1.函数原型及参数 function ...