From 003dc0dc2bdf7a11d68bfb3c0bd3495c6f3064bd Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Mon, 20 Oct 2014 17:19:28 -0400 Subject: [PATCH] Pass errors to DS in C++ and Java Squashed commit of the following: commit f317b3522e312cf7e7bb9eb0494f2f96a7f6363c Author: Kevin O'Connor Date: Mon Oct 20 17:15:46 2014 -0400 Send unhandled exceptions back to the DS. Change-Id: I0e658fdb6d43593ee20457f20f71f4f4cd2d21c3 commit f834ef8c791945697ad483c27b4167eb917ac242 Author: Kevin O'Connor Date: Mon Oct 20 16:05:24 2014 -0400 Add StackTrace to Java errors Change-Id: I83b162afcc5f294703705770fbcd8623b0895539 commit 02e040b0c79067ce046ada29e26004e0460fceb0 Author: Kevin O'Connor Date: Mon Oct 20 15:07:44 2014 -0400 HAL Errors to DS in Java Change-Id: I5fb51e4066bbc26ea59ca513c03c5ec5ace98831 commit 03775ddc42b129c27fdf403f17f0796009311c3c Author: Kevin O'Connor Date: Mon Oct 20 13:38:18 2014 -0400 Update AnalogInput to report errors for getting and setting sample rate Change-Id: I00eb78f52fc5b17a60bc84456f0ec9842cc40ef7 commit 4c10cb79612ae81e3cbb6bd4d6da8cf3b8955821 Author: Kevin O'Connor Date: Mon Oct 20 11:46:03 2014 -0400 Define errors in HAL Change-Id: I96595472e42ba61f0f3d0da17caf01a748d0422a commit 56cb5dcd93e5e849a016f63ac9d0dc245a23eb2b Author: Kevin O'Connor Date: Fri Oct 17 10:59:29 2014 -0400 Throttle errors (1 report per second per error code) and fix issue with GetTime conflicting with GetTime from Timer.h/Timer.cpp Change-Id: Ibe4dc2e400fc4671b240b876a46959256ea65ad7 commit 71c78826e548682ecd0c1548255f8a6552cece32 Author: Kevin O'Connor Date: Thu Oct 16 16:41:04 2014 -0400 Feed errors to DS from C++ Change-Id: I009a7798499fd93e9fdd976ff00aa74c0bd094ae commit 81030c6cee7f18a5ddf0e95c4e402a6cf7b5de6c Author: Kevin O'Connor Date: Thu Oct 16 16:40:50 2014 -0400 Don't try to de-mangle lines without any symbols in them Change-Id: Icea02494b68f2ec9116d6cbf20a35a3a132234f8 Change-Id: If7717025b03914183736ccd95da5c9d49819a6f3 --- hal/include/HAL/Errors.hpp | 69 +++++++++----- hal/lib/Athena/HAL.cpp | 95 +++++++++++++------ wpilibc/wpilibC++/include/Error.h | 2 +- wpilibc/wpilibC++/src/Error.cpp | 23 +++-- .../wpilibC++Devices/include/DriverStation.h | 1 + wpilibc/wpilibC++Devices/src/AnalogInput.cpp | 2 + .../wpilibC++Devices/src/DriverStation.cpp | 10 ++ wpilibc/wpilibC++Devices/src/Utility.cpp | 4 +- wpilibc/wpilibC++Sim/include/DriverStation.h | 3 + wpilibc/wpilibC++Sim/src/DriverStation.cpp | 11 ++- .../edu/wpi/first/wpilibj/DriverStation.java | 20 ++++ .../java/edu/wpi/first/wpilibj/RobotBase.java | 4 +- .../java/edu/wpi/first/wpilibj/Utility.java | 2 + .../FRCNetworkCommunicationsLibrary.java | 40 +------- .../edu/wpi/first/wpilibj/hal/HALUtil.java | 38 +++----- .../lib/FRCNetworkCommunicationsLibrary.cpp | 21 +++- .../edu/wpi/first/wpilibj/DriverStation.java | 19 ++++ 17 files changed, 237 insertions(+), 127 deletions(-) diff --git a/hal/include/HAL/Errors.hpp b/hal/include/HAL/Errors.hpp index 9428b00801..785b5bfae2 100644 --- a/hal/include/HAL/Errors.hpp +++ b/hal/include/HAL/Errors.hpp @@ -1,26 +1,47 @@ #pragma once -#define SAMPLE_RATE_TOO_HIGH 1 -#define SAMPLE_RATE_TOO_HIGH_MESSAGE "Analog module sample rate is too high" -#define VOLTAGE_OUT_OF_RANGE 2 -#define VOLTAGE_OUT_OF_RANGE_MESSAGE "Voltage to convert to raw value is out of range [0; 5]" -#define LOOP_TIMING_ERROR 4 -#define LOOP_TIMING_ERROR_MESSAGE "Digital module loop timing is not the expected value" -#define SPI_WRITE_NO_MOSI 12 -#define SPI_WRITE_NO_MOSI_MESSAGE "Cannot write to SPI port with no MOSI output" -#define SPI_READ_NO_MISO 13 -#define SPI_READ_NO_MISO_MESSAGE "Cannot read from SPI port with no MISO input" -#define SPI_READ_NO_DATA 14 -#define SPI_READ_NO_DATA_MESSAGE "No data available to read from SPI" -#define INCOMPATIBLE_STATE 15 -#define INCOMPATIBLE_STATE_MESSAGE "Incompatible State: The operation cannot be completed" -#define NO_AVAILABLE_RESOURCES -4 -#define NO_AVAILABLE_RESOURCES_MESSAGE "No available resources to allocate" -#define NULL_PARAMETER -5 -#define NULL_PARAMETER_MESSAGE "A pointer parameter to a method is NULL" -#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR -10 -#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE "AnalogTrigger limits error. Lower limit > Upper Limit" -#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR -11 -#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE "Attempted to read AnalogTrigger pulse output." -#define PARAMETER_OUT_OF_RANGE -28 -#define PARAMETER_OUT_OF_RANGE_MESSAGE "A parameter is out of range." +#define CTR_RxTimeout_MESSAGE "CTRE CAN Recieve Timeout" +#define CTR_TxTimeout_MESSAGE "CTRE CAN Transmit Timeout" +#define CTR_InvalidParamValue_MESSAGE "CTRE CAN Invalid Parameter" +#define CTR_UnexpectedArbId_MESSAGE "CTRE Unexpected Arbitration ID (CAN Node ID)" + +#define NiFpga_Status_FifoTimeout_MESSAGE "NIFPGA: FIFO timeout error" +#define NiFpga_Status_TransferAborted_MESSAGE "NIFPGA: Transfer aborted error" +#define NiFpga_Status_MemoryFull_MESSAGE "NIFPGA: Memory Allocation failed, memory full" +#define NiFpga_Status_SoftwareFault_MESSAGE "NIFPGA: Unexepected software error" +#define NiFpga_Status_InvalidParameter_MESSAGE "NIFPGA: Invalid Parameter" +#define NiFpga_Status_ResourceNotFound_MESSAGE "NIFPGA: Resource not found" +#define NiFpga_Status_ResourceNotInitialized_MESSAGE "NIFPGA: Resource not initialized" +#define NiFpga_Status_HardwareFault_MESSAGE "NIFPGA: Hardware Fault" +#define NiFpga_Status_IrqTimeout_MESSAGE "NIFPGA: Interrupt timeout" + +#define ERR_CANSessionMux_InvalidBuffer_MESSAGE "CAN: Invalid Buffer" +#define ERR_CANSessionMux_MessageNotFound_MESSAGE "CAN: Message not found" +#define WARN_CANSessionMux_NoToken_MESSAGE "CAN: No token" +#define ERR_CANSessionMux_NotAllowed_MESSAGE "CAN: Not allowed" +#define ERR_CANSessionMux_NotInitialized_MESSAGE "CAN: Not initialized" + +#define SAMPLE_RATE_TOO_HIGH 1001 +#define SAMPLE_RATE_TOO_HIGH_MESSAGE "HAL: Analog module sample rate is too high" +#define VOLTAGE_OUT_OF_RANGE 1002 +#define VOLTAGE_OUT_OF_RANGE_MESSAGE "HAL: Voltage to convert to raw value is out of range [0; 5]" +#define LOOP_TIMING_ERROR 1004 +#define LOOP_TIMING_ERROR_MESSAGE "HAL: Digital module loop timing is not the expected value" +#define SPI_WRITE_NO_MOSI 1012 +#define SPI_WRITE_NO_MOSI_MESSAGE "HAL: Cannot write to SPI port with no MOSI output" +#define SPI_READ_NO_MISO 1013 +#define SPI_READ_NO_MISO_MESSAGE "HAL: Cannot read from SPI port with no MISO input" +#define SPI_READ_NO_DATA 1014 +#define SPI_READ_NO_DATA_MESSAGE "HAL: No data available to read from SPI" +#define INCOMPATIBLE_STATE 1015 +#define INCOMPATIBLE_STATE_MESSAGE "HAL: Incompatible State: The operation cannot be completed" +#define NO_AVAILABLE_RESOURCES -1004 +#define NO_AVAILABLE_RESOURCES_MESSAGE "HAL: No available resources to allocate" +#define NULL_PARAMETER -1005 +#define NULL_PARAMETER_MESSAGE "HAL: A pointer parameter to a method is NULL" +#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR -1010 +#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE "HAL: AnalogTrigger limits error. Lower limit > Upper Limit" +#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR -1011 +#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE "HAL: Attempted to read AnalogTrigger pulse output." +#define PARAMETER_OUT_OF_RANGE -1028 +#define PARAMETER_OUT_OF_RANGE_MESSAGE "HAL: A parameter is out of range." diff --git a/hal/lib/Athena/HAL.cpp b/hal/lib/Athena/HAL.cpp index 258473cd88..f16b6c5f59 100644 --- a/hal/lib/Athena/HAL.cpp +++ b/hal/lib/Athena/HAL.cpp @@ -2,6 +2,7 @@ #include "Port.h" #include "HAL/Errors.hpp" +#include "ctre/ctre.h" #include "ChipObject.h" #include "NetworkCommunication/FRCComm.h" #include "NetworkCommunication/UsageReporting.h" @@ -38,34 +39,72 @@ void* getPortWithModule(uint8_t module, uint8_t pin) const char* getHALErrorMessage(int32_t code) { - if (code == 0) - return ""; - else if (code == SAMPLE_RATE_TOO_HIGH) - return SAMPLE_RATE_TOO_HIGH_MESSAGE; - else if (code == VOLTAGE_OUT_OF_RANGE) - return VOLTAGE_OUT_OF_RANGE_MESSAGE; - else if (code == LOOP_TIMING_ERROR) - return LOOP_TIMING_ERROR_MESSAGE; - else if (code == SPI_WRITE_NO_MOSI) - return SPI_WRITE_NO_MOSI_MESSAGE; - else if (code == SPI_READ_NO_MISO) - return SPI_READ_NO_MISO_MESSAGE; - else if (code == SPI_READ_NO_DATA) - return SPI_READ_NO_DATA_MESSAGE; - else if (code == INCOMPATIBLE_STATE) - return INCOMPATIBLE_STATE_MESSAGE; - else if (code == NO_AVAILABLE_RESOURCES) - return NO_AVAILABLE_RESOURCES_MESSAGE; - else if (code == NULL_PARAMETER) - return NULL_PARAMETER_MESSAGE; - else if (code == ANALOG_TRIGGER_LIMIT_ORDER_ERROR) - return ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE; - else if (code == ANALOG_TRIGGER_PULSE_OUTPUT_ERROR) - return ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE; - else if (code == PARAMETER_OUT_OF_RANGE) - return PARAMETER_OUT_OF_RANGE_MESSAGE; - else - return ""; + switch(code) { + case 0: + return ""; + case CTR_RxTimeout: + return CTR_RxTimeout_MESSAGE; + case CTR_TxTimeout: + return CTR_TxTimeout_MESSAGE; + case CTR_InvalidParamValue: + return CTR_InvalidParamValue_MESSAGE; + case CTR_UnexpectedArbId: + return CTR_UnexpectedArbId_MESSAGE; + case NiFpga_Status_FifoTimeout: + return NiFpga_Status_FifoTimeout_MESSAGE; + case NiFpga_Status_TransferAborted: + return NiFpga_Status_TransferAborted_MESSAGE; + case NiFpga_Status_MemoryFull: + return NiFpga_Status_MemoryFull_MESSAGE; + case NiFpga_Status_SoftwareFault: + return NiFpga_Status_SoftwareFault_MESSAGE; + case NiFpga_Status_InvalidParameter: + return NiFpga_Status_InvalidParameter_MESSAGE; + case NiFpga_Status_ResourceNotFound: + return NiFpga_Status_ResourceNotFound_MESSAGE; + case NiFpga_Status_ResourceNotInitialized: + return NiFpga_Status_ResourceNotInitialized_MESSAGE; + case NiFpga_Status_HardwareFault: + return NiFpga_Status_HardwareFault_MESSAGE; + case NiFpga_Status_IrqTimeout: + return NiFpga_Status_IrqTimeout_MESSAGE; + case SAMPLE_RATE_TOO_HIGH: + return SAMPLE_RATE_TOO_HIGH_MESSAGE; + case VOLTAGE_OUT_OF_RANGE: + return VOLTAGE_OUT_OF_RANGE_MESSAGE; + case LOOP_TIMING_ERROR: + return LOOP_TIMING_ERROR_MESSAGE; + case SPI_WRITE_NO_MOSI: + return SPI_WRITE_NO_MOSI_MESSAGE; + case SPI_READ_NO_MISO: + return SPI_READ_NO_MISO_MESSAGE; + case SPI_READ_NO_DATA: + return SPI_READ_NO_DATA_MESSAGE; + case INCOMPATIBLE_STATE: + return INCOMPATIBLE_STATE_MESSAGE; + case NO_AVAILABLE_RESOURCES: + return NO_AVAILABLE_RESOURCES_MESSAGE; + case NULL_PARAMETER: + return NULL_PARAMETER_MESSAGE; + case ANALOG_TRIGGER_LIMIT_ORDER_ERROR: + return ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE; + case ANALOG_TRIGGER_PULSE_OUTPUT_ERROR: + return ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE; + case PARAMETER_OUT_OF_RANGE: + return PARAMETER_OUT_OF_RANGE_MESSAGE; + case ERR_CANSessionMux_InvalidBuffer: + return ERR_CANSessionMux_InvalidBuffer_MESSAGE; + case ERR_CANSessionMux_MessageNotFound: + return ERR_CANSessionMux_MessageNotFound_MESSAGE; + case WARN_CANSessionMux_NoToken: + return WARN_CANSessionMux_NoToken_MESSAGE; + case ERR_CANSessionMux_NotAllowed: + return ERR_CANSessionMux_NotAllowed_MESSAGE; + case ERR_CANSessionMux_NotInitialized: + return ERR_CANSessionMux_NotInitialized_MESSAGE; + default: + return "Unknown error status"; + } } /** diff --git a/wpilibc/wpilibC++/include/Error.h b/wpilibc/wpilibC++/include/Error.h index 16bdd560f9..4fbe0f016b 100644 --- a/wpilibc/wpilibC++/include/Error.h +++ b/wpilibc/wpilibC++/include/Error.h @@ -29,7 +29,7 @@ public: const char *GetFunction() const; uint32_t GetLineNumber() const; const ErrorBase* GetOriginatingObject() const; - double GetTime() const; + double GetTimestamp() const; void Clear(); void Set(Code code, const char* contextMessage, const char* filename, const char *function, uint32_t lineNumber, const ErrorBase* originatingObject); diff --git a/wpilibc/wpilibC++/src/Error.cpp b/wpilibc/wpilibC++/src/Error.cpp index f377e22450..f64c4fe966 100644 --- a/wpilibc/wpilibC++/src/Error.cpp +++ b/wpilibc/wpilibC++/src/Error.cpp @@ -8,13 +8,12 @@ #include #include -#include #include #include #include #include "HAL/Task.hpp" -//#include "NetworkCommunication/FRCComm.h" +#include "DriverStation.h" #include "Timer.h" #include "Utility.h" bool Error::m_suspendOnErrorEnabled = false; @@ -58,20 +57,30 @@ uint32_t Error::GetLineNumber() const const ErrorBase* Error::GetOriginatingObject() const { return m_originatingObject; } -double Error::GetTime() const +double Error::GetTimestamp() const { return m_timestamp; } void Error::Set(Code code, const char* contextMessage, const char* filename, const char* function, uint32_t lineNumber, const ErrorBase* originatingObject) { + bool report = true; + + if(code == m_code && GetTime() - m_timestamp < 1) + { + report = false; + } + m_code = code; m_message = contextMessage; m_filename = filename; m_function = function; m_lineNumber = lineNumber; m_originatingObject = originatingObject; - m_timestamp = GetTime(); - Report(); + if(report) + { + m_timestamp = GetTime(); + Report(); + } if (m_suspendOnErrorEnabled) suspendTask(0); } @@ -87,9 +96,7 @@ void Error::Report() std::string error = errorStream.str(); - // Print the error and send it to the DriverStation - std::cout << error << std::endl; - // TODO: Better logging HALSetErrorData(error.c_str(), error.size(), 100); + DriverStation::ReportError(error); } void Error::Clear() diff --git a/wpilibc/wpilibC++Devices/include/DriverStation.h b/wpilibc/wpilibC++Devices/include/DriverStation.h index cae65d7527..1c45e8554a 100644 --- a/wpilibc/wpilibC++Devices/include/DriverStation.h +++ b/wpilibc/wpilibC++Devices/include/DriverStation.h @@ -28,6 +28,7 @@ public: virtual ~DriverStation(); static DriverStation *GetInstance(); + static void ReportError(std::string error); static const uint32_t kJoystickPorts = 4; diff --git a/wpilibc/wpilibC++Devices/src/AnalogInput.cpp b/wpilibc/wpilibC++Devices/src/AnalogInput.cpp index 77d1a047a4..c9e45b3160 100644 --- a/wpilibc/wpilibC++Devices/src/AnalogInput.cpp +++ b/wpilibc/wpilibC++Devices/src/AnalogInput.cpp @@ -387,6 +387,7 @@ void AnalogInput::SetSampleRate(float samplesPerSecond) { int32_t status = 0; setAnalogSampleRate(samplesPerSecond, &status); + wpi_setGlobalErrorWithContext(status, getHALErrorMessage(status)); } /** @@ -398,6 +399,7 @@ float AnalogInput::GetSampleRate() { int32_t status = 0; float sampleRate = getAnalogSampleRate(&status); + wpi_setGlobalErrorWithContext(status, getHALErrorMessage(status)); return sampleRate; } diff --git a/wpilibc/wpilibC++Devices/src/DriverStation.cpp b/wpilibc/wpilibC++Devices/src/DriverStation.cpp index 403732537a..e1ca182761 100644 --- a/wpilibc/wpilibC++Devices/src/DriverStation.cpp +++ b/wpilibc/wpilibC++Devices/src/DriverStation.cpp @@ -366,3 +366,13 @@ double DriverStation::GetMatchTime() return 0.0; return Timer::GetFPGATimestamp() - m_approxMatchTimeOffset; } + +/** + * Report an error to the DriverStation messages window. + * The error is also printed to the program console. + */ +void DriverStation::ReportError(std::string error) +{ + std::cout << error << std::endl; + HALSetErrorData(error.c_str(), error.size(), 0); +} diff --git a/wpilibc/wpilibC++Devices/src/Utility.cpp b/wpilibc/wpilibC++Devices/src/Utility.cpp index e533537f69..2f72d0e7e1 100644 --- a/wpilibc/wpilibC++Devices/src/Utility.cpp +++ b/wpilibc/wpilibC++Devices/src/Utility.cpp @@ -225,10 +225,10 @@ static std::string demangle(char const *mangledSymbol) size_t length; int status; - if(sscanf(mangledSymbol, "%*[^(]%*[^_]%255[^)+]", buffer)) + + if(sscanf(mangledSymbol, "%*[^(]%*[(]%255[^)+]", buffer)) { char *symbol = abi::__cxa_demangle(buffer, NULL, &length, &status); - if(status == 0) { return symbol; diff --git a/wpilibc/wpilibC++Sim/include/DriverStation.h b/wpilibc/wpilibC++Sim/include/DriverStation.h index 31a4c085da..dbac051bdf 100644 --- a/wpilibc/wpilibC++Sim/include/DriverStation.h +++ b/wpilibc/wpilibC++Sim/include/DriverStation.h @@ -31,6 +31,7 @@ public: virtual ~DriverStation(); static DriverStation *GetInstance(); + static void ReportError(std::string error); static const uint32_t kBatteryChannel = 7; static const uint32_t kJoystickPorts = 4; @@ -59,6 +60,8 @@ public: double GetMatchTime(); float GetBatteryVoltage(); uint16_t GetTeamNumber(); + + void IncrementUpdateNumber() { diff --git a/wpilibc/wpilibC++Sim/src/DriverStation.cpp b/wpilibc/wpilibC++Sim/src/DriverStation.cpp index b959c12730..fef168ba5a 100644 --- a/wpilibc/wpilibC++Sim/src/DriverStation.cpp +++ b/wpilibc/wpilibC++Sim/src/DriverStation.cpp @@ -60,7 +60,7 @@ DriverStation::DriverStation() &DriverStation::joystickCallback2, this); joysticks[2] = msgs::JoystickPtr(new msgs::Joystick()); joysticksSub[2] = MainNode::Subscribe("~/ds/joysticks/3", - &DriverStation::joystickCallback3, this); + &DriverStation::joystickCallback3, this); joysticks[3] = msgs::JoystickPtr(new msgs::Joystick()); joysticksSub[3] = MainNode::Subscribe("~/ds/joysticks/4", &DriverStation::joystickCallback4, this); @@ -325,6 +325,15 @@ double DriverStation::GetMatchTime() return Timer::GetFPGATimestamp() - m_approxMatchTimeOffset; } +/** + * Report an error to the DriverStation messages window. + * The error is also printed to the program console. + */ +void DriverStation::ReportError(std::string error) +{ + std::cout << error << std::endl; +} + /** * Return the team number that the Driver Station is configured for * @return The team number diff --git a/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/DriverStation.java b/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/DriverStation.java index 0ec655e8db..65b714198a 100644 --- a/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/DriverStation.java +++ b/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/DriverStation.java @@ -400,6 +400,26 @@ public class DriverStation implements RobotState.Interface { } return Timer.getFPGATimestamp() - m_approxMatchTimeOffset; } + + /** + * Report error to Driver Station. + * Also prints error to System.err + * Optionally appends Stack trace to error message + * @param printTrace If true, append stack trace to error string + */ + public static void reportError(String error, boolean printTrace) { + String errorString = error; + if(printTrace) { + errorString += " at "; + StackTraceElement[] traces = Thread.currentThread().getStackTrace(); + for (int i=2; i 0) { + String message = getHALErrorMessage(s); + DriverStation.reportError(message, true); } } diff --git a/wpilibj/wpilibJavaJNI/lib/FRCNetworkCommunicationsLibrary.cpp b/wpilibj/wpilibJavaJNI/lib/FRCNetworkCommunicationsLibrary.cpp index 9588265456..e4d5b4e6df 100644 --- a/wpilibj/wpilibJavaJNI/lib/FRCNetworkCommunicationsLibrary.cpp +++ b/wpilibj/wpilibJavaJNI/lib/FRCNetworkCommunicationsLibrary.cpp @@ -88,8 +88,8 @@ JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_communication_FRCNetworkCommun JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_communication_FRCNetworkCommunicationsLibrary_FRCNetworkCommunicationUsageReportingReport (JNIEnv * paramEnv, jclass, jbyte paramResource, jbyte paramInstanceNumber, jbyte paramContext, jstring paramFeature) { - NETCOMM_LOG(logDEBUG) << "Calling FRCNetworkCommunicationsLibrary report " << "res:"<< (unsigned int)paramResource << " instance:" << (unsigned int)paramInstanceNumber << " context:" << (unsigned int)paramContext << " feature:" << paramFeature; const char * featureStr = paramEnv->GetStringUTFChars(paramFeature, NULL); + NETCOMM_LOG(logDEBUG) << "Calling FRCNetworkCommunicationsLibrary report " << "res:"<< (unsigned int)paramResource << " instance:" << (unsigned int)paramInstanceNumber << " context:" << (unsigned int)paramContext << " feature:" << featureStr; jint returnValue = HALReport(paramResource, paramInstanceNumber, paramContext, featureStr); paramEnv->ReleaseStringUTFChars(paramFeature,featureStr); return returnValue; @@ -534,3 +534,22 @@ JNIEXPORT jobject JNICALL Java_edu_wpi_first_wpilibj_communication_FRCNetworkCom return env->NewDirectByteBuffer(returnByteArray, 4); } + +/* + * Class: edu_wpi_first_wpilibj_communication_FRCNetworkCommunicationsLibrary + * Method: HALSetErrorData + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_communication_FRCNetworkCommunicationsLibrary_HALSetErrorData + (JNIEnv * env, jclass, jstring error) +{ + const char * errorStr = env->GetStringUTFChars(error, NULL); + jsize length = env->GetStringUTFLength(error); + + NETCOMM_LOG(logDEBUG) << "Set Error: " << errorStr; + NETCOMM_LOG(logDEBUG) << "Length: " << length; + jint returnValue = HALSetErrorData(errorStr, (jint) length, 0); + env->ReleaseStringUTFChars(error,errorStr); + return returnValue; +} + diff --git a/wpilibj/wpilibJavaSim/src/main/java/edu/wpi/first/wpilibj/DriverStation.java b/wpilibj/wpilibJavaSim/src/main/java/edu/wpi/first/wpilibj/DriverStation.java index ccde3af219..addc39c4a9 100644 --- a/wpilibj/wpilibJavaSim/src/main/java/edu/wpi/first/wpilibj/DriverStation.java +++ b/wpilibj/wpilibJavaSim/src/main/java/edu/wpi/first/wpilibj/DriverStation.java @@ -283,6 +283,25 @@ public class DriverStation implements RobotState.Interface { public boolean isFMSAttached() { return false; } + + /** + * Report error to Driver Station. + * Also prints error to System.err + * Optionally appends Stack trace to error message + * @param printTrace If true, append stack trace to error string + */ + public static void reportError(String error, boolean printTrace) { + String errorString = error; + if(printTrace) { + errorString += " at "; + StackTraceElement[] traces = Thread.currentThread().getStackTrace(); + for (int i=2; i