Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Joystick Smoothing

Status
Not open for further replies.

sweep123

Technical User
May 1, 2003
185
0
0
GB
I have developed a MFC VC++ application with a joystick as an input device.

Does anyone have any code to smooth out the action.

Currently would like roll and pitch smoothed to -/+ 180 from the 0 to 65756 values used by the joystick.

i.e. dip a few desgrees/sec while joystick off-centre.

Any comments?
 
Hi Sweep123;
I am a student Of electrical engineering.
I want ot simply work with Joystick in VC++ 6.
Can you please help me.
Thank you very much;
 
Hi,

you should use a moving average technique for first try (should be appropriate solution).
1. Sum up the last n sampled values
2. divide the result by (n * 360)
3. subtract 180 from result.
4. The result you get it smoothened and mapped to -180..180.

Should be very easy to implement.

Hope I could help you, Daniel
 
Sorry,

step 3 should be : divide the result by (n*65756 / 360).
 
Hi EMKH, sorry for the delay, but some code for you, its MFC C++
// MSCPPDlg.cpp : implementation file
//

#include "stdafx.h"
#include "MSCPP.h"
#include "MSCPPDlg.h"
#include <MMSYSTEM.H>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// Global data
JOYINFO joyInfo;
bool testWithMouse = true;
int StartX, StartY; // Declare at the top of the form’s unit
CString strFormatting;
bool ButtonDown = false;
static bool capture = false;

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
CAboutDlg();

// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMSCPPDlg dialog

CMSCPPDlg::CMSCPPDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMSCPPDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMSCPPDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMSCPPDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMSCPPDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMSCPPDlg, CDialog)
//{{AFX_MSG_MAP(CMSCPPDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_GET_STATUS, OnGetStatus)
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
ON_MESSAGE(MM_JOY1BUTTONDOWN, OnJoy1ButtonDown)
ON_MESSAGE(MM_JOY1BUTTONUP, OnJoy1ButtonUp)
ON_MESSAGE(MM_JOY1MOVE, OnJoy1Move)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMSCPPDlg message handlers

BOOL CMSCPPDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

int error;
if(!capture)
{ // Start the capture
error = joySetCapture(this->m_hWnd, JOYSTICKID1, NULL, FALSE);
switch (error)
{
case MMSYSERR_NODRIVER :
MessageBox("The joystick driver is not present", "Error when capturing", MB_ICONERROR);
break;
case MMSYSERR_INVALPARAM :
MessageBox("Windows 95/98/Me: Invalid joystick ID or hwnd is NULL.", "Error when capturing", MB_ICONERROR);
break;
case JOYERR_NOCANDO :
MessageBox("Cannot capture joystick input because a required service (such as a Windows timer) is unavailable.", "Error when capturing", MB_ICONERROR);
break;
case JOYERR_UNPLUGGED :
MessageBox("The specified joystick is not connected to the system. ", "Error when capturing", MB_ICONERROR);
break;
default :
MessageBox("The joystick has been captured");
capture = true;
}

}
else
{ // Release the Joystick capture
joyReleaseCapture(JOYSTICKID1);
capture = false;
MessageBox("The joystick has been released");
}
return TRUE; // return TRUE unless you set the focus to a control
}

void CMSCPPDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.

void CMSCPPDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}

// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMSCPPDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}

void CMSCPPDlg::OnGetStatus()
{
/* This procedure determines the status of any joysticks that the system may
have. If none is detected then the user is informet. */

CString formatData;
JOYCAPS joyCaps; // This structure contains information about the
// joysticks capabilities
if(joyGetDevCaps(JOYSTICKID1, &joyCaps, sizeof(joyCaps)) == JOYERR_NOERROR)
{
// Joystick detected
SetDlgItemText(IDC_STATUS,"Joystick 1 Detected");
formatData.Format("%d", joyCaps.wMid);
SetDlgItemText(IDC_MANU2, formatData);
formatData.Format("%d", formatData);
SetDlgItemText(IDC_MANU3, formatData);
formatData.Format("%d", joyCaps.szPname);
SetDlgItemText(IDC_MANU4, formatData);
// SetDlgItemText(lblNoButtons->Caption + joyCaps.wNumButtons);
// SetDlgItemText(lblNoButtons->Caption + " Max No of Axes = ");
// SetDlgItemText(lblNoButtons->Caption + joyCaps.wMaxAxes);
// SetDlgItemText(lblNoButtons->Caption + " Number Used = ");
// SetDlgItemText(lblNoButtons->Caption + joyCaps.wNumAxes);
formatData.Format("%d", joyCaps.wXmin);
SetDlgItemText(IDC_XMIN,formatData);
formatData.Format("%d", joyCaps.wYmin);
SetDlgItemText(IDC_YMIN,formatData);
formatData.Format("%d", joyCaps.wZmin);
SetDlgItemText(IDC_ZMIN,formatData);
formatData.Format("%d", joyCaps.wXmax);
SetDlgItemText(IDC_XMAX,formatData);
formatData.Format("%d", joyCaps.wYmax);
SetDlgItemText(IDC_YMAX,formatData);
formatData.Format("%d", joyCaps.wZmax);
SetDlgItemText(IDC_ZMAX, formatData);
}
else
{
SetDlgItemText(IDC_STATUS,"Joystick Driver Not Detected");
}
}


LRESULT CMSCPPDlg::OnJoy1ButtonDown(WPARAM wParam, LPARAM lParam)
{
if (wParam & JOY_BUTTON1)
MessageBox("The joystick Button 1 Pressed");
else if (wParam & JOY_BUTTON2)
MessageBox("The joystick Button 2 Pressed");
else if (wParam & JOY_BUTTON3)
MessageBox("The joystick Button 3 Pressed");
else if (wParam & JOY_BUTTON4)
MessageBox("The joystick Button 4 Pressed");
return 0;
}
LRESULT CMSCPPDlg::OnJoy1Move(WPARAM wParam, LPARAM lParam)
{
int errorVal; // Error returned from the joyGetPos call

errorVal = joyGetPos(JOYSTICKID1, &joyInfo);
switch (errorVal)
{
case MMSYSERR_NODRIVER :
MessageBox("The joystick driver is not present");
break;
case MMSYSERR_INVALPARAM :
MessageBox("An invalid parameter was passed");
break;
case JOYERR_UNPLUGGED :
MessageBox("The joystick is not connected");
break;
default : // Update the joysticks x,y,z position
strFormatting.Format("%d", joyInfo.wXpos);
SetDlgItemText(IDC_X_DATA, strFormatting);
strFormatting.Format("%d", joyInfo.wYpos);
SetDlgItemText(IDC_Y_DATA, strFormatting);
strFormatting.Format("%d", joyInfo.wZpos);
SetDlgItemText(IDC_Z_DATA, strFormatting);
UpdateData();
}

return 0;
}
LRESULT CMSCPPDlg::OnJoy1ButtonUp(WPARAM wParam, LPARAM lParam)
{
/* This procedure will annotate the joystrick button that has been released. */
if(wParam & JOY_BUTTON1CHG)
{
MessageBox("The joystick Button 1 Released");
}
else
if(wParam & JOY_BUTTON2CHG)
{
MessageBox("The joystick Button 2 Released");
}
else
if(wParam & JOY_BUTTON3CHG)
{
MessageBox("The joystick Button 3 Released");
}
else
if(wParam & JOY_BUTTON4CHG)
{
MessageBox("The joystick Button 4 Released");
}
return 0;
}

void CMSCPPDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
if ( ButtonDown ) return;
ButtonDown = TRUE;
SetCapture();
}

void CMSCPPDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
if ( !ButtonDown ) return;
ReleaseCapture();
ButtonDown = false;
}

void CMSCPPDlg::OnMouseMove(UINT nFlags, CPoint point)
{
if ( !ButtonDown ) return;

strFormatting.Format("%d", point.x);
SetDlgItemText(IDC_X_DATA_MOUSE, strFormatting);
strFormatting.Format("%d", point.y);
SetDlgItemText(IDC_Y_DATA_MOUSE, strFormatting);
UpdateData();
}
when capturing",
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top