static void Main(string[] args) { uint hHD = HDAPI.hdInitDevice(null); HDAPI.hdEnable(HDEDParameters.HD_FORCE_OUTPUT); HDAPI.hdStartScheduler(); HDErrorInfo error = HDAPI.hdGetError(); if (error.CheckedError()) { Console.WriteLine("Start Scheduler Failed."); Console.ReadKey(); return; } ulong pHandler = HDAPI.hdScheduleAsynchronous(FrictionlessSphereCallback, IntPtr.Zero, HDSchedulerPriority.HD_DEFAULT_SCHEDULER_PRIORITY); while (true) { if (HDAPI.hdWaitForCompletion(pHandler, HDWaitCode.HD_WAIT_CHECK_STATUS) == 0x00) { Console.WriteLine("主回调器退出。"); Console.ReadKey(); return; } } HDAPI.hdStopScheduler(); HDAPI.hdUnschedule(pHandler); HDAPI.hdDisableDevice(hHD); }
static void Main(string[] args) { uint hHD = HDAPI.hdInitDevice(null); Console.WriteLine(HLAPI.hlGetString(HLGetStringParameters.HL_VENDOR)); HDAPI.hdMakeCurrentDevice(hHD); IntPtr hHLRC = HLAPI.hlCreateContext(hHD); HLAPI.hlMakeCurrent(hHLRC); //禁用GL HLAPI.hlDisable(HLCapabilityParameters.HL_USE_GL_MODELVIEW); uint spring = HLAPI.hlGenEffects(1); Console.WriteLine("spring:{0}", spring); //添加回调处理按扭按下 HLAPI.hlAddEventCallback(HLCallbackEvents.HL_EVENT_1BUTTONDOWN, HLAPI.HL_OBJECT_ANY, HLCallbackThreads.HL_CLIENT_THREAD, ButtonCB, new IntPtr(spring)); HLAPI.hlAddEventCallback(HLCallbackEvents.HL_EVENT_1BUTTONUP, HLAPI.HL_OBJECT_ANY, HLCallbackThreads.HL_CLIENT_THREAD, ButtonCB, new IntPtr(spring)); HLAPI.hlAddEventCallback(HLCallbackEvents.HL_EVENT_2BUTTONDOWN, HLAPI.HL_OBJECT_ANY, HLCallbackThreads.HL_CLIENT_THREAD, ButtonCB, new IntPtr(0)); uint friction = HLAPI.hlGenEffects(1); HLAPI.hlBeginFrame(); HLAPI.hlEffectd(HLEffectParams.HL_EFFECT_PROPERTY_GAIN, 0.2); HLAPI.hlEffectd(HLEffectParams.HL_EFFECT_PROPERTY_MAGNITUDE, 0.5); HLAPI.hlStartEffect(HLStartEffectTypes.HL_EFFECT_FRICTION, friction); HLAPI.hlEndFrame(); HLError error; while (true) { HLAPI.hlBeginFrame(); //轮询事件。请注意,客户端线程事件回调是从这里的一个框架内分派的,因此我们可以安全地直接启动/停止事件回调的效果 HLAPI.hlCheckEvents(); HLAPI.hlEndFrame(); error = HLAPI.hlGetError(); if (error.CheckedError()) { Console.WriteLine("HL Error:{0}", error.GetErrorCodeString()); } } //Stop the friction effect. HLAPI.hlBeginFrame(); HLAPI.hlStopEffect(friction); HLAPI.hlEndFrame(); HLAPI.hlDeleteEffects(friction, 1); HLAPI.hlDeleteEffects(spring, 1); HLAPI.hlDeleteContext(hHLRC); HDAPI.hdDisableDevice(hHD); Console.ReadKey(); }
static void Main(string[] args) { uint hHD = HDAPI.hdInitDevice("Default Device"); error = HDAPI.hdGetError(); if (error.CheckedError()) { Console.WriteLine("Device Initialize Failed.."); Console.ReadKey(); return; } //HDSchedulerCallback pCallback = GravityWellCallback; ulong gravityWell = HDAPI.hdScheduleAsynchronous(GravityWellCallback, IntPtr.Zero, HDSchedulerPriority.HD_MAX_SCHEDULER_PRIORITY); HDAPI.hdEnable(HDEDParameters.HD_FORCE_OUTPUT); HDAPI.hdStartScheduler(); error = HDAPI.hdGetError(); if (error.CheckedError()) { Console.WriteLine("Start Scheduler Failed.."); Console.ReadKey(); return; } while (true) { ConsoleKeyInfo key = Console.ReadKey(); if (key.Key == ConsoleKey.DownArrow) { InForce = true; Console.WriteLine("In Force:{0}", true); } else if (key.Key == ConsoleKey.UpArrow) { InForce = false; Console.WriteLine("Out Force:{0}", false); } if (HDAPI.hdWaitForCompletion(gravityWell, HDWaitCode.HD_WAIT_CHECK_STATUS) == 0x00) { Console.WriteLine("Ready quit.."); Console.ReadKey(); break; } } HDAPI.hdStopScheduler(); HDAPI.hdUnschedule(gravityWell); HDAPI.hdDisableDevice(hHD); }
static void Main(string[] args) { uint hHD = HDAPI.hdInitDevice(null); HDErrorInfo error = HDAPI.hdGetError(); if (error.CheckedError()) { Console.WriteLine("Initialize Device Failed."); Console.ReadKey(); return; } HDAPI.hdMakeCurrentDevice(hHD); IntPtr hHLRC = HLAPI.hlCreateContext(hHD); HLAPI.hlMakeCurrent(hHLRC); HLAPI.hlDisable(HLCapabilityParameters.HL_USE_GL_MODELVIEW); uint spring = HLAPI.hlGenEffects(1); IntPtr ptr = new IntPtr(spring); HLAPI.hlAddEventCallback(HLCallbackEvents.HL_EVENT_1BUTTONDOWN, HLAPI.HL_OBJECT_ANY, HLCallbackThreads.HL_CLIENT_THREAD, ButtonCB, ptr); HLAPI.hlAddEventCallback(HLCallbackEvents.HL_EVENT_1BUTTONUP, HLAPI.HL_OBJECT_ANY, HLCallbackThreads.HL_CLIENT_THREAD, ButtonCB, ptr); while (true) { HLAPI.hlBeginFrame(); //轮询事件。请注意,客户端线程事件回调是从这里的一个框架内分派的,因此我们可以安全地直接启动/停止事件回调的效果。 HLAPI.hlCheckEvents(); HLAPI.hlEndFrame(); } HLAPI.hlDeleteEffects(spring, 1); HLAPI.hlDeleteContext(hHLRC); HDAPI.hdDisableDevice(hHD); }
static void Main(string[] args) { uint hHD = HDAPI.hdInitDevice(HDAPI.HD_DEFAULT_DEVICE); error = HDAPI.hdGetError(); if (error.CheckedError()) { Console.WriteLine("Device Initialize Failed.."); return; } //更新校准 //HDAPI.hdUpdateCalibration(HDCalibrationStyles.HD_CALIBRATION_INKWELL); HDSchedulerCallback pCallback = AnchoredSpringForceHandler; IntPtr deviceHHD = new IntPtr(hHD); ulong pHandler = HDAPI.hdScheduleAsynchronous(pCallback, deviceHHD, HDSchedulerPriority.HD_MAX_SCHEDULER_PRIORITY); //启用力输出功能 HDAPI.hdEnable(HDEDParameters.HD_FORCE_OUTPUT); double maxStiffness = 0; //查询设备能够处理的最大闭环控制刚度。使用超过这个限制的值可能会导致设备嗡嗡作响。 HDAPI.hdGetDoublev(HDGetParameters.HD_NOMINAL_MAX_STIFFNESS, ref maxStiffness); HDAPI.hdStartScheduler(); error = HDAPI.hdGetError(); if (error.CheckedError()) { Console.WriteLine("启动调度程序失败."); Console.ReadKey(); return; } Console.WriteLine("按下 Button 1 开始,按上下键设置 force 值"); while (true) { ConsoleKeyInfo key = Console.ReadKey(true); if (key.Key == ConsoleKey.DownArrow) { gSpringStiffness -= 0.05; if (gSpringStiffness <= 0) { gSpringStiffness = 0.00; } Console.WriteLine("gSpringStiffness:{0}", gSpringStiffness); } else if (key.Key == ConsoleKey.UpArrow) { gSpringStiffness += 0.05; if (gSpringStiffness >= maxStiffness) { gSpringStiffness = maxStiffness; } Console.WriteLine("gSpringStiffness:{0}", gSpringStiffness); } } HDAPI.hdStopScheduler(); HDAPI.hdUnschedule(pHandler); HDAPI.hdDisableDevice(hHD); }
static void Main(string[] args) { hHD = HDAPI.hdInitDevice(null); error = HDAPI.hdGetError(); if (error.CheckedError()) { Console.WriteLine("Init Error."); Console.ReadKey(); return; } //获取支持的校准样式,因为一些设备可能支持多种类型的校准 HDAPI.hdGetIntegerv(HDGetParameters.HD_CALIBRATION_STYLE, ref supportedCalibrationStyles); Console.WriteLine("supportedCalibrationStyles:{0} {1}", supportedCalibrationStyles, Enum.GetName(typeof(HDCalibrationStyles), supportedCalibrationStyles)); //使用墨水池校准 HDAPI.hdUpdateCalibration(HDCalibrationStyles.HD_CALIBRATION_INKWELL); //启动 Servo Loop HDAPI.hdStartScheduler(); #if 直接获取坐标位置输出 double[] pPosition = new double[3]; int buttons = 0; while (true) { if (HDAPI.hdCheckCalibration() == HDCalibrationCodes.HD_CALIBRATION_NEEDS_UPDATE) { HDAPI.hdUpdateCalibration(HDCalibrationStyles.HD_CALIBRATION_INKWELL); } HDAPI.hdBeginFrame(hHD); HDAPI.hdGetDoublev(HDGetParameters.HD_CURRENT_POSITION, pPosition); HDAPI.hdGetIntegerv(HDGetParameters.HD_CURRENT_BUTTONS, ref buttons); HDAPI.hdEndFrame(hHD); Console.WriteLine("Button Status:Btn1:{0} Btn2:{1} Btn3:{2} Btn4:{3}", buttons & (int)HDButtonMasks.HD_DEVICE_BUTTON_1, buttons & (int)HDButtonMasks.HD_DEVICE_BUTTON_2, buttons & (int)HDButtonMasks.HD_DEVICE_BUTTON_3, buttons & (int)HDButtonMasks.HD_DEVICE_BUTTON_4); Console.WriteLine("Position: X:{0} Y:{1} Z:{2}", pPosition[0], pPosition[1], pPosition[2]); Thread.Sleep(100); } #endif #if 使用调度器同步输出位置 PositionSynchronous = GetSyncPos; Vector3D v3 = new Vector3D(); v3.HHD = hHD; IntPtr pPosition = OHUtils.StructToIntPtr(v3); while (true) { HDAPI.hdScheduleSynchronous(PositionSynchronous, pPosition, HDSchedulerPriority.HD_DEFAULT_SCHEDULER_PRIORITY); v3 = OHUtils.IntPtrToStruct <Vector3D>(pPosition); Console.WriteLine("Position: X:{0} Y:{1} Z:{2}", v3.X, v3.Y, v3.Z); //Sleep一下,不然打印的数据太多,看不清,实际项目是不需要的 //Thread.Sleep(100); } #endif //停止 Servo Loop HDAPI.hdStopScheduler(); //禁用设备 HDAPI.hdDisableDevice(hHD); Console.ReadKey(); return; }