Skip to content

Commit a3e770a

Browse files
authored
Merge pull request #23 from dmadison/sequential-fix
Fix Logitech G25 Sequential Shifting Direction
2 parents 64cbb7e + 274bf91 commit a3e770a

File tree

2 files changed

+58
-29
lines changed

2 files changed

+58
-29
lines changed

src/SimRacing.cpp

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ void AnalogShifter::serialCalibration(Stream& iface) {
11031103
iface.println(separator);
11041104
iface.println();
11051105

1106-
iface.print(F("shifter.setCalibration( "));
1106+
iface.print(F("shifter.setCalibration("));
11071107

11081108
for (int i = 0; i < 7; i++) {
11091109
iface.print('{');
@@ -1421,7 +1421,7 @@ LogitechShifterG25::LogitechShifterG25(
14211421
{
14221422
// using the calibration values from my own G25 shifter
14231423
this->setCalibration({ 508, 435 }, { 310, 843 }, { 303, 8 }, { 516, 827 }, { 540, 14 }, { 713, 846 }, { 704, 17 });
1424-
this->setCalibrationSequential(425, 619, 257);
1424+
this->setCalibrationSequential(425, 257, 619);
14251425
}
14261426

14271427
void LogitechShifterG25::begin() {
@@ -1463,17 +1463,17 @@ bool LogitechShifterG25::updateState(bool connected) {
14631463

14641464
// if we're neutral, check for up/down shift
14651465
if (this->sequentialState == 0) {
1466-
if (y >= this->seqCalibration.upTrigger) this->sequentialState = 1;
1467-
else if (y <= this->seqCalibration.downTrigger) this->sequentialState = -1;
1466+
if (y <= this->seqCalibration.upTrigger) this->sequentialState = 1;
1467+
else if (y >= this->seqCalibration.downTrigger) this->sequentialState = -1;
14681468
}
14691469

14701470
// if we're in up-shift mode, check for release
1471-
else if ((this->sequentialState == 1) && (y < this->seqCalibration.upRelease)) {
1471+
else if ((this->sequentialState == 1) && (y > this->seqCalibration.upRelease)) {
14721472
this->sequentialState = 0;
14731473
}
14741474

14751475
// if we're in down-shift mode, check for release
1476-
else if ((this->sequentialState == -1) && (y > this->seqCalibration.downRelease)) {
1476+
else if ((this->sequentialState == -1) && (y < this->seqCalibration.downRelease)) {
14771477
this->sequentialState = 0;
14781478
}
14791479

@@ -1526,16 +1526,34 @@ void LogitechShifterG25::setCalibrationSequential(int neutral, int up, int down,
15261526
releasePoint = engagePoint;
15271527
}
15281528

1529+
// if up/down calibration points are reversed, swap them
1530+
//
1531+
// in the original public release, pushing the shifter was 'shift up'
1532+
// and pulling the shifter was 'shift down'
1533+
//
1534+
// this bug was eventually fixed, so that now pushing the shifter is
1535+
// 'shift down' and pulling the shifter is 'shift up'. This matches the
1536+
// markings on the shifter itself (or mine, at least), and mirrors the
1537+
// behavior of a sequential shift lever in a real rally car.
1538+
//
1539+
// by swapping the calibration points here, the function maintains
1540+
// compatibility with calibration lines written for both versions
1541+
if(up > down) {
1542+
int temp = up;
1543+
up = down; // dogs and cats living together, mass hysteria
1544+
down = temp;
1545+
}
1546+
15291547
// calculate ranges
1530-
const int upRange = up - neutral;
1531-
const int downRange = neutral - down;
1548+
const int upRange = neutral - up;
1549+
const int downRange = down - neutral;
15321550

15331551
// calculate calibration points
1534-
this->seqCalibration.upTrigger = neutral + (upRange * engagePoint);
1535-
this->seqCalibration.upRelease = neutral + (upRange * releasePoint);
1552+
this->seqCalibration.upTrigger = neutral - (upRange * engagePoint);
1553+
this->seqCalibration.upRelease = neutral - (upRange * releasePoint);
15361554

1537-
this->seqCalibration.downTrigger = neutral - (downRange * engagePoint);
1538-
this->seqCalibration.downRelease = neutral - (downRange * releasePoint);
1555+
this->seqCalibration.downTrigger = neutral + (downRange * engagePoint);
1556+
this->seqCalibration.downRelease = neutral + (downRange * releasePoint);
15391557
}
15401558

15411559
void LogitechShifterG25::serialCalibrationSequential(Stream& iface) {
@@ -1582,23 +1600,23 @@ void LogitechShifterG25::serialCalibrationSequential(Stream& iface) {
15821600

15831601
const uint8_t NumPoints = 3;
15841602
const char* directions[2][2] = {
1585-
{ "away from you", "up" },
1586-
{ "towards you", "down" },
1603+
{ "pull", "towards you" },
1604+
{ "push", "away from you" },
15871605
};
15881606
int data[NumPoints];
15891607

15901608
int& neutral = data[0];
1591-
int& yMax = data[1];
1592-
int& yMin = data[2];
1609+
int& yMin = data[1];
1610+
int& yMax = data[2];
15931611

15941612
for (uint8_t i = 0; i < NumPoints; ++i) {
15951613
if (i == 0) {
15961614
iface.print(F("Leave the gear shifter in neutral"));
15971615
}
15981616
else {
1599-
iface.print(F("Please move the gear shifter "));
1617+
iface.print(F("Please "));
16001618
iface.print(directions[i - 1][0]);
1601-
iface.print(F(" to sequentially shift "));
1619+
iface.print(F(" the gear shifter "));
16021620
iface.print(directions[i - 1][1]);
16031621
iface.print(F(" and hold it there"));
16041622
}
@@ -1607,7 +1625,12 @@ void LogitechShifterG25::serialCalibrationSequential(Stream& iface) {
16071625

16081626
this->update();
16091627
data[i] = this->getPositionRaw(Axis::Y);
1610-
iface.println(); // spacing
1628+
1629+
iface.print(F("Shifter position recorded as "));
1630+
iface.print('\'');
1631+
iface.print(data[i]);
1632+
iface.print('\'');
1633+
iface.println('\n'); // spacing
16111634
}
16121635

16131636
iface.println(F("These settings are optional. Send 'y' to customize. Send any other character to continue with the default values."));
@@ -1635,20 +1658,20 @@ void LogitechShifterG25::serialCalibrationSequential(Stream& iface) {
16351658
flushClient(iface);
16361659

16371660
// apply and print
1638-
this->setCalibrationSequential(neutral, yMax, yMin, engagementPoint, releasePoint);
1661+
this->setCalibrationSequential(neutral, yMin, yMax, engagementPoint, releasePoint);
16391662

16401663
iface.println(F("Here is your calibration:"));
16411664
iface.println(separator);
16421665
iface.println();
16431666

1644-
iface.print(F("shifter.setCalibrationSequential( "));
1667+
iface.print(F("shifter.setCalibrationSequential("));
16451668

16461669
iface.print(neutral);
16471670
iface.print(", ");
1648-
iface.print(yMax);
1649-
iface.print(", ");
16501671
iface.print(yMin);
16511672
iface.print(", ");
1673+
iface.print(yMax);
1674+
iface.print(", ");
16521675

16531676
iface.print(engagementPoint);
16541677
iface.print(", ");

src/SimRacing.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,18 +1154,24 @@ namespace SimRacing {
11541154
bool inSequentialMode() const;
11551155

11561156
/**
1157-
* Check if the sequential shifter is shifted up
1157+
* Check if the sequential shifter is in the shift up position
1158+
*
1159+
* When in sequential mode, the shifter is considered to be in the
1160+
* "shift up" position when it is pulled towards the user.
11581161
*
1159-
* @returns 'true' if the sequential shifter is shifted up,
1160-
* 'false' otherwise
1162+
* @returns 'true' if the sequential shifter is in the shift up
1163+
* position, 'false' otherwise
11611164
*/
11621165
bool getShiftUp() const;
11631166

11641167
/**
1165-
* Check if the sequential shifter is shifted down
1168+
* Check if the sequential shifter is in the shift down position
11661169
*
1167-
* @returns 'true' if the sequential shifter is shifted down,
1168-
* 'false' otherwise
1170+
* When in sequential mode, the shifter is considered to be in the
1171+
* "shift down" position when it is pushed away from the user.
1172+
*
1173+
* @returns 'true' if the sequential shifter is in the shift down
1174+
* position, 'false' otherwise
11691175
*/
11701176
bool getShiftDown() const;
11711177

0 commit comments

Comments
 (0)