Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions src/joysticks.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,19 @@ void DS_JoysticksReset(void)
register_event();
}

/*
* WPILib HAL joystick limits
*/
#define WPILIB_MAX_AXES 12
#define WPILIB_MAX_BUTTONS 32
#define WPILIB_MAX_POVS 12

/**
* Registers a new joystick with the given number of \a axes, \a hats and
* \a buttons. All joystick values are set to a neutral state to ensure
* safe operation of the robot.
*
* Values are clamped to WPILib limits to prevent protocol errors.
*/
void DS_JoysticksAdd(const int axes, const int hats, const int buttons)
{
Expand All @@ -229,13 +238,18 @@ void DS_JoysticksAdd(const int axes, const int hats, const int buttons)
return;
}

/* Clamp to WPILib limits */
int clamped_axes = (axes > WPILIB_MAX_AXES) ? WPILIB_MAX_AXES : axes;
int clamped_hats = (hats > WPILIB_MAX_POVS) ? WPILIB_MAX_POVS : hats;
int clamped_buttons = (buttons > WPILIB_MAX_BUTTONS) ? WPILIB_MAX_BUTTONS : buttons;

/* Allocate memory for a new joystick */
DS_Joystick *joystick = (DS_Joystick *)calloc(1, sizeof(DS_Joystick));

/* Set joystick properties */
joystick->num_axes = axes;
joystick->num_hats = hats;
joystick->num_buttons = buttons;
/* Set joystick properties (clamped to WPILib limits) */
joystick->num_axes = clamped_axes;
joystick->num_hats = clamped_hats;
joystick->num_buttons = clamped_buttons;

/* Set joystick value arrays */
joystick->hats = calloc(hats, sizeof(int));
Expand Down
52 changes: 35 additions & 17 deletions src/protocols/frc_2020.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,18 +280,32 @@ static uint8_t get_station_code(void)
}

/**
* Returns the size of the given \a joystick. This function is used to generate
* joystick data (which is sent to the robot) and to resize the client->robot
* datagram automatically.
* Returns the number of bytes needed to encode the button bitmask.
* WPILib expects (numButtons + 7) / 8 bytes.
*/
static int get_button_bytes(const int num_buttons)
{
if (num_buttons <= 0)
return 0;
return (num_buttons + 7) / 8;
}

/**
* Returns the size of the given \a joystick data block (NOT including the
* length byte itself). This function is used to generate joystick data
* (which is sent to the robot) and to resize the client->robot datagram.
*
* Format: [tag][axes_count][axes...][button_count][button_bytes...][pov_count][povs...]
*/
static uint8_t get_joystick_size(const int joystick)
{
int header_size = 2;
int button_data = DS_GetJoystickNumButtons(joystick) + 1;
int axis_data = DS_GetJoystickNumAxes(joystick) + 1;
int hat_data = (DS_GetJoystickNumHats(joystick) * 2) + 1;
int tag_size = 1; /* Tag byte (0x0c) - included in length */
int num_buttons = DS_GetJoystickNumButtons(joystick);
int button_data = 1 + get_button_bytes(num_buttons); /* count + bitmask bytes */
int axis_data = 1 + DS_GetJoystickNumAxes(joystick); /* count + axis bytes */
int hat_data = 1 + (DS_GetJoystickNumHats(joystick) * 2); /* count + 2 bytes per hat */

return header_size + button_data + axis_data + hat_data;
return tag_size + axis_data + button_data + hat_data;
}

/**
Expand Down Expand Up @@ -383,16 +397,20 @@ static DS_String get_joystick_data(void)
for (j = 0; j < DS_GetJoystickNumAxes(i); ++j)
DS_StrAppend(&data, DS_FloatToByte(DS_GetJoystickAxis(i, j), 1));

/* Generate button data */
uint16_t button_flags = 0;
for (j = 0; j < DS_GetJoystickNumButtons(i); ++j)
button_flags += DS_GetJoystickButton(i, j) ? (int)pow(2, j) : 0;
/* Generate button bitmask (supports up to 32 buttons) */
int num_buttons = DS_GetJoystickNumButtons(i);
uint32_t button_flags = 0;
for (j = 0; j < num_buttons; ++j)
if (DS_GetJoystickButton(i, j))
button_flags |= (1u << j);

/* Add button count */
DS_StrAppend(&data, (uint8_t)num_buttons);

/* Add button data */
/* potential TODO: this assumes num_buttons <= 16 */
DS_StrAppend(&data, DS_GetJoystickNumButtons(i));
DS_StrAppend(&data, (uint8_t)(button_flags >> 8));
DS_StrAppend(&data, (uint8_t)(button_flags));
/* Add button bitmask bytes in big-endian order (high bytes first) */
int button_bytes = get_button_bytes(num_buttons);
for (j = button_bytes - 1; j >= 0; --j)
DS_StrAppend(&data, (uint8_t)(button_flags >> (j * 8)));

/* Add hat data */
DS_StrAppend(&data, DS_GetJoystickNumHats(i));
Expand Down
26 changes: 13 additions & 13 deletions wrappers/Qt/EventLogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ void DSEventLogger::saveDataLoop()
void DSEventLogger::onCANUsageChanged(int usage)
{
Q_UNUSED(usage);
m_canUsageLog.append(qMakePair<qint64, int>(currentTime(), usage));
m_canUsageLog.append(QPair<qint64, int>(currentTime(), usage));
}

/**
Expand All @@ -285,7 +285,7 @@ void DSEventLogger::onCANUsageChanged(int usage)
void DSEventLogger::onCPUUsageChanged(int usage)
{
Q_UNUSED(usage);
m_cpuUsageLog.append(qMakePair<qint64, int>(currentTime(), usage));
m_cpuUsageLog.append(QPair<qint64, int>(currentTime(), usage));
}

/**
Expand All @@ -294,7 +294,7 @@ void DSEventLogger::onCPUUsageChanged(int usage)
void DSEventLogger::onRAMUsageChanged(int usage)
{
Q_UNUSED(usage);
m_ramUsageLog.append(qMakePair<qint64, int>(currentTime(), usage));
m_ramUsageLog.append(QPair<qint64, int>(currentTime(), usage));
}

/**
Expand All @@ -303,7 +303,7 @@ void DSEventLogger::onRAMUsageChanged(int usage)
void DSEventLogger::onNewMessage(QString message)
{
Q_UNUSED(message);
m_messagesLog.append(qMakePair<qint64, QString>(currentTime(), message));
m_messagesLog.append(QPair<qint64, QString>(currentTime(), message));
}

/**
Expand All @@ -312,7 +312,7 @@ void DSEventLogger::onNewMessage(QString message)
void DSEventLogger::onDiskUsageChanged(int usage)
{
Q_UNUSED(usage);
m_diskUsageLog.append(qMakePair<qint64, int>(currentTime(), usage));
m_diskUsageLog.append(QPair<qint64, int>(currentTime(), usage));
}

/**
Expand All @@ -321,7 +321,7 @@ void DSEventLogger::onDiskUsageChanged(int usage)
void DSEventLogger::onEnabledChanged(bool enabled)
{
LOG << "Robot enabled state set to" << enabled;
m_enabledLog.append(qMakePair<qint64, bool>(currentTime(), enabled));
m_enabledLog.append(QPair<qint64, bool>(currentTime(), enabled));
}

/**
Expand All @@ -338,7 +338,7 @@ void DSEventLogger::onTeamNumberChanged(int number)
void DSEventLogger::onVoltageChanged(float voltage)
{
Q_UNUSED(voltage);
m_voltageLog.append(qMakePair<qint64, float>(currentTime(), voltage));
m_voltageLog.append(QPair<qint64, float>(currentTime(), voltage));
}

/**
Expand All @@ -347,7 +347,7 @@ void DSEventLogger::onVoltageChanged(float voltage)
void DSEventLogger::onRobotCodeChanged(bool robotCode)
{
LOG << "Robot code status set to" << robotCode;
m_robotCodeLog.append(qMakePair<qint64, bool>(currentTime(), robotCode));
m_robotCodeLog.append(QPair<qint64, bool>(currentTime(), robotCode));
}

/**
Expand All @@ -356,7 +356,7 @@ void DSEventLogger::onRobotCodeChanged(bool robotCode)
void DSEventLogger::onFMSCommunicationsChanged(bool connected)
{
LOG << "FMS communications set to" << connected;
m_fmsCommsLog.append(qMakePair<qint64, bool>(currentTime(), connected));
m_fmsCommsLog.append(QPair<qint64, bool>(currentTime(), connected));
}

/**
Expand All @@ -365,7 +365,7 @@ void DSEventLogger::onFMSCommunicationsChanged(bool connected)
void DSEventLogger::onRadioCommunicationsChanged(bool connected)
{
LOG << "Radio communications set to" << connected;
m_radioCommsLog.append(qMakePair<qint64, bool>(currentTime(), connected));
m_radioCommsLog.append(QPair<qint64, bool>(currentTime(), connected));
}

/**
Expand All @@ -374,7 +374,7 @@ void DSEventLogger::onRadioCommunicationsChanged(bool connected)
void DSEventLogger::onRobotCommunicationsChanged(bool connected)
{
LOG << "Robot communications set to" << connected;
m_robotCommsLog.append(qMakePair<qint64, bool>(currentTime(), connected));
m_robotCommsLog.append(QPair<qint64, bool>(currentTime(), connected));
}

/**
Expand All @@ -383,7 +383,7 @@ void DSEventLogger::onRobotCommunicationsChanged(bool connected)
void DSEventLogger::onEmergencyStoppedChanged(bool emergencyStopped)
{
LOG << "ESTOP set to" << emergencyStopped;
m_emergencyStopLog.append(qMakePair<qint64, bool>(currentTime(), emergencyStopped));
m_emergencyStopLog.append(QPair<qint64, bool>(currentTime(), emergencyStopped));
}

/**
Expand All @@ -392,7 +392,7 @@ void DSEventLogger::onEmergencyStoppedChanged(bool emergencyStopped)
void DSEventLogger::onControlModeChanged(DriverStation::Control mode)
{
LOG << "Robot control mode set to" << mode;
m_controlModeLog.append(qMakePair<qint64, int>(currentTime(), (int)mode));
m_controlModeLog.append(QPair<qint64, int>(currentTime(), (int)mode));
}

/**
Expand Down