Commit 5ee18daf authored by Bryant's avatar Bryant

Added an inversion checkbox for each joystick axis so they can be individually...

Added an inversion checkbox for each joystick axis so they can be individually inverted or not. This will be a joystick-specific configuration and independent of the autopilot used. Also refactored the code so that the JoystickAxis objects connect directly to the JoystickInput thread for updating the backend. The JoystickWidget is now just a facilitator and doesn't do any redirecting itself.
parent 8999151e
......@@ -45,9 +45,6 @@ JoystickInput::JoystickInput() :
calibrationNegative[i] = sdlJoystickMin;
}
// Listen for when the active UAS changes so we can change who we're sending data to.
connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));
// Start this thread. This allows the Joystick Settings window to work correctly even w/o any UASes connected.
start();
}
......@@ -191,7 +188,15 @@ void JoystickInput::run()
{
// First emit the uncalibrated values for each axis based on their ID.
// This is generally not used for controlling a vehicle, but a UI representation, so it being slightly off is fine.
float axisValue = (SDL_JoystickGetAxis(joystick, i) - calibrationNegative[i]) / (calibrationPositive[i] - calibrationNegative[i]);
float axisValue = SDL_JoystickGetAxis(joystick, i);
if (joystickAxesInverted[i])
{
axisValue = (axisValue - calibrationNegative[i]) / (calibrationPositive[i] - calibrationNegative[i]);
}
else
{
axisValue = (axisValue - calibrationPositive[i]) / (calibrationNegative[i] - calibrationPositive[i]);
}
axisValue = 1.0f - axisValue;
axisValue = axisValue * 2.0f - 1.0f;
......@@ -270,11 +275,14 @@ void JoystickInput::setActiveJoystick(int id)
// Update cached joystick values
joystickAxes.clear();
joystickAxesInverted.clear();
for (int i = 0; i < joystickNumAxes; i++)
{
int axisValue = SDL_JoystickGetAxis(joystick, i);
joystickAxes.append(axisValue);
emit axisValueChanged(i, axisValue);
joystickAxesInverted.append(false);
}
joystickButtons = 0;
for (int i = 0; i < joystickNumButtons; i++)
......@@ -294,11 +302,57 @@ void JoystickInput::setActiveJoystick(int id)
}
}
float JoystickInput::getCurrentValueForAxis(int axisID)
void JoystickInput::setAxisMapping(int axis, JOYSTICK_INPUT_MAPPING newMapping)
{
switch (newMapping)
{
case JOYSTICK_INPUT_MAPPING_ROLL:
rollAxis = axis;
break;
case JOYSTICK_INPUT_MAPPING_PITCH:
pitchAxis = axis;
break;
case JOYSTICK_INPUT_MAPPING_YAW:
yawAxis = axis;
break;
case JOYSTICK_INPUT_MAPPING_THROTTLE:
throttleAxis = axis;
break;
case JOYSTICK_INPUT_MAPPING_NONE:
default:
if (rollAxis == axis)
{
rollAxis = -1;
}
if (pitchAxis == axis)
{
pitchAxis = -1;
}
if (yawAxis == axis)
{
yawAxis = -1;
}
if (throttleAxis == axis)
{
throttleAxis = -1;
}
break;
}
}
void JoystickInput::setAxisInversion(int axis, bool inverted)
{
if (axis < joystickAxesInverted.size())
{
joystickAxesInverted[axis] = inverted;
}
}
float JoystickInput::getCurrentValueForAxis(int axis)
{
if (axisID < joystickAxes.size())
if (axis < joystickAxes.size())
{
return joystickAxes[axisID];
return joystickAxes[axis];
}
return 0.0f;
}
......@@ -130,7 +130,7 @@ public:
return QString(SDL_JoystickName(id));
}
float getCurrentValueForAxis(int axisID);
float getCurrentValueForAxis(int axis);
const double sdlJoystickMin;
const double sdlJoystickMax;
......@@ -157,6 +157,7 @@ protected:
int joystickNumButtons;
QList<float> joystickAxes; ///< The values of every axes during the last sample
QList<bool> joystickAxesInverted; ///< Whether each axis should be used inverted from what was reported
quint16 joystickButtons; ///< The state of every button. Bitfield supporting 16 buttons with 1s indicating that the button is down.
int xHat, yHat; ///< The horizontal/vertical hat directions. Values are -1, 0, 1, with (-1,-1) indicating bottom-left.
......@@ -214,29 +215,23 @@ signals:
void hatDirectionChanged(int x, int y);
public slots:
/** @brief Specify the UAS that this input should forward joystickChanged signals and buttonPresses to. */
void setActiveUAS(UASInterface* uas);
/** @brief Switch to a new joystick by ID number. Both buttons and axes are updated with the proper signals emitted. */
void setActiveJoystick(int id);
void setMappingRollAxis(int axis)
{
rollAxis = axis;
}
void setMappingPitchAxis(int axis)
{
pitchAxis = axis;
}
void setMappingYawAxis(int axis)
{
yawAxis = axis;
}
void setMappingThrottleAxis(int axis)
{
throttleAxis = axis;
}
/**
* @brief Change the control mapping for a given joystick axis.
* @param axisID The axis to modify (0-indexed)
* @param newMapping The mapping to use.
* @see JOYSTICK_INPUT_MAPPING
*/
void setAxisMapping(int axis, JOYSTICK_INPUT_MAPPING newMapping);
/**
* @brief Specify if an axis should be inverted.
* @param axis The ID of the axis.
* @param inverted True indicates inverted from normal. Varies by controller.
*/
void setAxisInversion(int axis, bool inverted);
};
#endif // _JOYSTICKINPUT_H_
......@@ -11,6 +11,7 @@ JoystickAxis::JoystickAxis(int id, QWidget *parent) :
ui->setupUi(this);
ui->label->setText(QString::number(id));
connect(ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(mappingComboBoxChanged(int)));
connect(ui->checkBox, SIGNAL(clicked(bool)), this, SLOT(inversionCheckBoxChanged(bool)));
}
JoystickAxis::~JoystickAxis()
......@@ -27,3 +28,8 @@ void JoystickAxis::mappingComboBoxChanged(int newMapping)
{
emit mappingChanged(id, (JoystickInput::JOYSTICK_INPUT_MAPPING)newMapping);
}
void JoystickAxis::inversionCheckBoxChanged(bool inverted)
{
emit inversionChanged(id, inverted);
}
......@@ -19,6 +19,8 @@ public:
signals:
/** @brief Signal a change in this axis' yaw/pitch/roll mapping */
void mappingChanged(int id, JoystickInput::JOYSTICK_INPUT_MAPPING newMapping);
/** @brief Signal a change in this axis' inversion status */
void inversionChanged(int id, bool);
public slots:
/** @brief Update the displayed value of the included progressbar.
......@@ -33,6 +35,8 @@ private:
private slots:
/** @brief Handle changes to the mapping dropdown bar. */
void mappingComboBoxChanged(int newMapping);
/** @brief Handle changes to the inversion checkbox. */
void inversionCheckBoxChanged(bool inverted);
};
#endif // JOYSTICKAXIS_H
......@@ -6,12 +6,12 @@
<rect>
<x>0</x>
<y>0</y>
<width>40</width>
<width>80</width>
<height>200</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
......@@ -120,6 +120,19 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Inverted</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
......
......@@ -132,7 +132,8 @@ void JoystickWidget::updateUIForJoystick(int id)
{
JoystickAxis* axis = new JoystickAxis(i, m_ui->axesBox);
axis->setValue(joystick->getCurrentValueForAxis(i));
connect(axis, SIGNAL(mappingChanged(int,JoystickInput::JOYSTICK_INPUT_MAPPING)), this, SLOT(setMappingAxis(int,JoystickInput::JOYSTICK_INPUT_MAPPING)));
connect(axis, SIGNAL(mappingChanged(int,JoystickInput::JOYSTICK_INPUT_MAPPING)), this->joystick, SLOT(setAxisMapping(int,JoystickInput::JOYSTICK_INPUT_MAPPING)));
connect(axis, SIGNAL(inversionChanged(int,bool)), this->joystick, SLOT(setAxisInversion(int,bool)));
// And make sure we insert BEFORE the vertical spacer.
m_ui->axesLayout->insertWidget(i, axis);
axes.append(axis);
......@@ -152,28 +153,6 @@ void JoystickWidget::setHat(int x, int y)
m_ui->statusLabel->setText(tr("Hat position: x: %1, y: %2").arg(x).arg(y));
}
void JoystickWidget::setMappingAxis(int axisID, JoystickInput::JOYSTICK_INPUT_MAPPING newMapping)
{
switch (newMapping)
{
case JoystickInput::JOYSTICK_INPUT_MAPPING_ROLL:
joystick->setMappingRollAxis(axisID);
break;
case JoystickInput::JOYSTICK_INPUT_MAPPING_PITCH:
joystick->setMappingPitchAxis(axisID);
break;
case JoystickInput::JOYSTICK_INPUT_MAPPING_YAW:
joystick->setMappingYawAxis(axisID);
break;
case JoystickInput::JOYSTICK_INPUT_MAPPING_THROTTLE:
joystick->setMappingThrottleAxis(axisID);
break;
case JoystickInput::JOYSTICK_INPUT_MAPPING_NONE:
default:
break;
}
}
void JoystickWidget::joystickButtonPressed(int key)
{
QString colorStyle = QString("QLabel { background-color: %1;}").arg(buttonLabelColor.name());
......
......@@ -55,8 +55,6 @@ public:
public slots:
/** @brief Update the UI for a new joystick based on SDL ID. */
void updateUIForJoystick(int id);
/** @brief Change the stored mapping for a given axis. */
void setMappingAxis(int axisID, JoystickInput::JOYSTICK_INPUT_MAPPING newMapping);
/**
* @brief Update a given axis with a new value
* @param axis The index of the axis to update.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment