使用飛行搖桿控制CNC C#版程式範例
這個羅技飛行搖桿本來是用在一個從頭城出發要去一個遙遠地方的大台UAV,看到挑戰國內法令的罰款可能會罰到脫褲子, 所以只能收手不玩了, 天空不能玩了, 就換地上及海上囉, 於是把程式移植到CNC, 運作起來還蠻順手的, 像是 夾娃娃機, 其實不管是CNC軸控、太空船、飛機或機器人, Joystick程式是一樣的。
以前玩Apple-II時曾經用6502組合語言改寫地球保衛戰的電玩, 大意是太空衛星發射雷射光射向入侵地球的飛碟, 但不可以射到底下建築物否則扣分, 這個CNC Demo頗有幾分神似呢, 特別是雷射扳機打開發射時, 感覺還蠻爽的^^
下面是控制搖桿程式庫TJoystick, 分享給有興趣的好友參考一下, 可很容易地加入自已的機台:
因為主程式很長, 所以只列出TJoystick程式庫, 主程式就不po了, 有興趣再私下討論了。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SharpDX;
using SharpDX.DirectInput;
namespace TJoystick
{
public enum JoyDirectionType
{
Center,
zUp,
zDown,
Up,
Right,
Down,
Left
}
//-------------------------------------------------------------------------
public class Joystick
{
SharpDX.DirectInput.DirectInput dirInput;
SharpDX.DirectInput.DeviceType typeJoystick;
IList<DeviceInstance> Devices;
SharpDX.DirectInput.Joystick curJoystick;
bool bJoystick;
int X, Y;
int RZ;
int Slider;
int POV;
int[] Buttons;
//-----------------------------------------------------------------------
public Joystick()
{
bJoystick = false;
X = 0;
Y = 0;
RZ = 0;
Slider = 0;
POV = -1; //中心點 = -1
Buttons = new int[7];
for(int i=0;i <7; i++)
Buttons[i] = 0;
}
//-----------------------------------------------------------------------
public SharpDX.DirectInput.DeviceInstance FindDevice()
{
SharpDX.DirectInput.DeviceInstance deviceInstance = new DeviceInstance();
deviceInstance.ProductName = "";
deviceInstance.InstanceName = "";
deviceInstance.InstanceGuid = Guid.Empty;
dirInput = new SharpDX.DirectInput.DirectInput();
typeJoystick = SharpDX.DirectInput.DeviceType.Joystick;
Devices = dirInput.GetDevices();
foreach (var device in Devices)
{
if (typeJoystick == device.Type)
{
deviceInstance.ProductName = device.ProductName;
deviceInstance.InstanceName = device.InstanceName;
deviceInstance.InstanceGuid = device.InstanceGuid;
break;
}
}
return deviceInstance;
} //public SharpDX.DirectInput.DeviceInstance Open()
//-----------------------------------------------------------------------
public bool Connect(SharpDX.DirectInput.DeviceInstance deviceInstance)
{
bJoystick = false;
if(deviceInstance.InstanceGuid != Guid.Empty)
{
bJoystick = true;
curJoystick = new SharpDX.DirectInput.Joystick(dirInput, deviceInstance.InstanceGuid);
// Set BufferSize in order to use buffered data.
//curJoystick.Properties.BufferSize = 128;
curJoystick.Acquire();
//curJoystick.Poll();
//curJoystick.GetCurrentState();
//Thread t1 = new Thread(PollThreadFunction);
//t1.IsBackground = true;
//t1.Start();
}
return bJoystick;
}
//-----------------------------------------------------------------------
public bool IsGetJoystick()
{
return bJoystick;
}
//-----------------------------------------------------------------------
public int[] GetJoystickData()
{
int[] data = new int[12];
data[0] = X;
data[1] = Y;
data[2] = RZ;
data[3] = Slider;
data[4] = POV;
for(int i=0; i<7; i++)
data[5 + i] = Buttons[i];
return data;
}
//-----------------------------------------------------------------------
public double NormalizationScale(double a, double b, int mindata, int maxdata)
{
double k=(b-a)/(maxdata - mindata);
return k;
}
//-----------------------------------------------------------------------
public double NormalizationData(double data, double a, double b, int mindata, int maxdata)
{
double k=(b-a)/(maxdata - mindata);
double normdata = a + k * (data - mindata);
if(normdata > b)
normdata = b;
else
if(normdata < a)
normdata = a;
return normdata;
}
//-----------------------------------------------------------------------
public double[] Signal_XY()
{
double[] data = new double[2];
data[0] = X;
data[1] = Y;
data[0] = NormalizationData(data[0], -128, 127, 69, 164);
data[1] = NormalizationData(data[1], -128, 127, 71, 201);
return data;
}
//-----------------------------------------------------------------------
public double Signal_RZ()
{
double rz = NormalizationData(RZ, -128, 127, 80, 216);
return rz;
}
//-----------------------------------------------------------------------
public double Signal_Slider()
{
double slider = NormalizationData(Slider, 0, 10, 45, 180);
return slider;
}
//-----------------------------------------------------------------------
public int[] Signal_POV()
{
int[] data = new int[2];
if(POV == -1) //Center
{
data[0] = -1;
data[1] = 0;
}
else
if(POV == 0) //Up
{
data[0] = 0;
data[1] = 0;
}
else
if(POV == 35) //Right
{
data[0] = 1;
data[1] = 0;
}
else
if(POV == 70) //Down
{
data[0] = 2;
data[1] = 0;
}
else
if(POV == 105) //Down
{
data[0] = 3;
data[1] = 0;
}
return data;
}
//-----------------------------------------------------------------------
public bool Signal_Button0()
{
if(Buttons[0] == 1)
return true;
return false;
}
//-----------------------------------------------------------------------
public void Poll()
{
try
{
//curJoystick.Acquire();
// poll the joystick
curJoystick.Poll();
// update the joystick state field
var joys = curJoystick.GetCurrentState();
X = joys.X >> 8; // X/256
Y = joys.Y >> 8; // Y/256
RZ = joys.RotationZ >> 8;
Slider = joys.Sliders[0] >> 8;
POV = joys.PointOfViewControllers[0] >> 8;
for(int i=0; i<7; i++)
Buttons[i] = Convert.ToInt32(joys.Buttons[i]);
}
catch (SystemException)
{
}
} //public void Poll()
//-----------------------------------------------------------------------
public void PollThreadFunction()
{
while(true)
{
Poll();
} //while(true)
} //public void JoystickThreadFunction()
} //public class TJoystick
} //namespace TJoystick
黃俊凱
2019-09-15 19:02:51
廖元佑
2019-09-15 19:39:01
Don Si
2019-09-16 13:25:58