I'd like a recommandation on how to approach the problem I'm facing as a software developer.
Context:
I have an IP Camera that can be moved with a PTZ (Pan, Tilt, Zoom) command that can be called like so:
PTZ(float pan, float tilt, float zoom)
I have a joystick that update its input values every ~0.0001 sec and the available input values are:
joystickX
: from -1(left) to 1(right) 0 being the centerjoystickY
: from -1(down) to 1(up) 0 being the centerjoystickMagnitude
: from 0(untouched) to 1(completely pushed)zoomButton+
: pressed(zoomValue
= 1) or notzoomButton-
: pressed(zoomValue
= -1) or not
Right now, every time the joystick values are updated, a message to the camera is sent, so it's kinda spamming the camera every ~0.0001 sec with PTZ
messages.
Ex:
- Joystick input value update
PTZ(joystickX*joystickMagnitude, joystickY*joystickMagnitude, zoomValue)
message sent- Repeat in ~0.0001 sec
Question:
What would be the best approach to be able to control the camera with the joystick without spamming PTZ
messages?
Here's what I have so far:
(Note that this is based on)
- How to use xbox one controller in C# application
- https://gamedev.stackexchange.com/questions/67651/what-is-the-standard-c-windows-forms-game-loop
So yeah
private void ConnectXboxController()
{
_xboxController = new XInputController();
if (_xboxController.Connected)
{
//set the update/render loop
Application.Idle += HandleApplicationIdle;
MessageBox.Show("The controller has been connected.");
}
else
{
MessageBox.Show("The controller could not be connected.");
}
}
private void DisconnectXboxController()
{
_xboxController = null;
Application.Idle -= HandleApplicationIdle;
MessageBox.Show("The controller has been disconnected.");
}
private void Update()
{
//Update xbox controller properties
if (!_xboxController.Update())
{
//Stop the loop
DisconnectXboxController();
}
}
private void Render()
{
//Render changes made to the xbox controller properties
try
{
if (_xboxController.LeftThumb.Magnitude != 0)
{
_moving = true;
_camera.PostPTZContinuous(
_xboxController.LeftThumb.Direction.X * _xboxController.LeftThumb.Magnitude * _camera.Speed,
_xboxController.LeftThumb.Direction.Y * _xboxController.LeftThumb.Magnitude * _camera.Speed,
0);
}
else
{
if (_moving == true)
{
_camera.PostPTZContinuous(0, 0, 0);
_moving = false;
UpdateCurrentStatus();
}
}
}
catch (Exception) { }
}
private bool IsApplicationIdle()
{
NativeMessage result;
return PeekMessage(out result, IntPtr.Zero, (uint)0, (uint)0, (uint)0) == 0;
}
private void HandleApplicationIdle(object sender, EventArgs e)
{
//Stops when the xbox controller is set to null
while (IsApplicationIdle() && _xboxController != null)
{
Update();
Render();
}
}
[StructLayout(LayoutKind.Sequential)]
public struct NativeMessage
{
public IntPtr Handle;
public uint Message;
public IntPtr WParameter;
public IntPtr LParameter;
public uint Time;
public Point Location;
}
[DllImport("user32.dll")]
private static extern int PeekMessage(out NativeMessage message, IntPtr window, uint filterMin, uint filterMax, uint remove);