Compare commits

...

11 Commits

Author SHA1 Message Date
Tyler Veness
12f759860e Corrects assumptions about return values from i2c-lib (#484)
Fixes #478
2017-02-17 00:05:54 -08:00
Austin Shalit
1bdbb5ddcc Remove usages of isEnable() (#483) 2017-02-14 01:16:36 -08:00
Paul Friederichsen
b573fb6555 Fix param order in RobotDrive docs (#481)
Fix Javadoc @param order in RobotDrive and fix order of params in C++ docs
2017-02-14 01:14:56 -08:00
Thad House
b50a7bdbee Fixes memory leak for SPI reads (#474)
Adds a stack allocation for most use cases.
2017-02-14 01:14:08 -08:00
Thad House
5a5f10dfc8 Fixes I2C read change size of pointer (#479)
Fixes #477
2017-02-10 15:21:59 -08:00
Peter Johnson
e375b4a9ff CameraServer: auto-increment startAutomaticCapture(). (#468)
Also add GetServer() functions so the automatically created VideoSink can
be retrieved by user code if desired.
2017-01-20 01:07:37 -07:00
Thad House
ff141ab1ff Fixes exception on camera creation without plugged in camera (#470)
Would throw if the camera was disconnected. We handle this properly at
the JNI level to not have this crash the entire program, but the error
is still kind of annoying, and not really an error.
2017-01-20 01:02:27 -07:00
Peter Johnson
b8537be219 CameraServer: Remove NT-driven settings. (#467)
Unfortunately, due to the way NT synchronization is currently performed,
this has unexpected and undesirable behavior: when a dashboard (or any other
NT client) is left running between code restarts, when it reconnects, any
code settings will be overwritten by the NT synchronization process.  As
fixing this will require a fairly major NT change (and likely a user-visible
one), it's not desirable to do at this point in the year.

Instead, disable NT driven settings entirely (e.g. make the NT interface
publish only).  To emphasize the read-only nature of the NT values, attempts
to change the NT values will be immediately overridden by CameraServer.

To better inform users about the actual property names (e.g. for use in their
code), the "raw_" settings no longer have "raw_" removed from their names
(they are still placed in the "RawProperty" subtable).

This change also contains a couple of Java fixes:

* Make getInstance() thread-safe

* Properly synchronize access to m_tables between multiple threads.

* Use Hashtable instead of HashMap.
2017-01-19 12:30:07 -07:00
Austin Shalit
8f1b034b2f Fix typo in JavaDoc (#462) 2017-01-16 22:57:28 -07:00
Thad House
71d0a07e0a Fixes solenoid allocation error message (#455)
The error was NO_AVAILABLE_RESOURCES, which is not the proper error to
return. Instead,  just return the error directly from the allocation.
2017-01-14 23:59:05 -07:00
sciencewhiz
d322342494 Remove comments about Blue DS (#450)
It's unlikely that anyone is still using the Blue Kwikbyte DS from 2009,
and the reference is confusing to people who weren't around then.
2017-01-14 23:52:48 -07:00
15 changed files with 174 additions and 106 deletions

View File

@@ -78,7 +78,7 @@ void HAL_InitializeI2C(int32_t port, int32_t* status) {
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into.
* @param receiveSize Number of bytes to read from the device.
* @return The number of bytes read (>= 0) or -1 on transfer abort.
* @return >= 0 on success or -1 on transfer abort.
*/
int32_t HAL_TransactionI2C(int32_t port, int32_t deviceAddress,
uint8_t* dataToSend, int32_t sendSize,
@@ -110,7 +110,7 @@ int32_t HAL_TransactionI2C(int32_t port, int32_t deviceAddress,
* @param registerAddress The address of the register on the device to be
* written.
* @param data The byte to write to the register on the device.
* @return The number of bytes written (>= 0) or -1 on transfer abort.
* @return >= 0 on success or -1 on transfer abort.
*/
int32_t HAL_WriteI2C(int32_t port, int32_t deviceAddress, uint8_t* dataToSend,
int32_t sendSize) {
@@ -140,7 +140,7 @@ int32_t HAL_WriteI2C(int32_t port, int32_t deviceAddress, uint8_t* dataToSend,
* @param count The number of bytes to read in the transaction.
* @param buffer A pointer to the array of bytes to store the data read from the
* device.
* @return The number of bytes read (>= 0) or -1 on transfer abort.
* @return >= 0 on success or -1 on transfer abort.
*/
int32_t HAL_ReadI2C(int32_t port, int32_t deviceAddress, uint8_t* buffer,
int32_t count) {

View File

@@ -55,8 +55,7 @@ HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
auto handle =
solenoidHandles.Allocate(module * kNumSolenoidChannels + channel, status);
if (handle == HAL_kInvalidHandle) { // out of resources
*status = NO_AVAILABLE_RESOURCES;
if (*status != 0) {
return HAL_kInvalidHandle;
}
auto solenoidPort = solenoidHandles.Get(handle);

View File

@@ -7,6 +7,7 @@
#pragma once
#include <atomic>
#include <memory>
#include <mutex>
#include <string>
@@ -44,8 +45,10 @@ class CameraServer : public ErrorBase {
* If you also want to perform vision processing on the roboRIO, use
* getVideo() to get access to the camera images.
*
* This overload calls {@link #StartAutomaticCapture(int)} with device 0,
* creating a camera named "USB Camera 0".
* The first time this overload is called, it calls
* {@link #StartAutomaticCapture(int)} with device 0, creating a camera
* named "USB Camera 0". Subsequent calls increment the device number
* (e.g. 1, 2, etc).
*/
cs::UsbCamera StartAutomaticCapture();
@@ -241,6 +244,21 @@ class CameraServer : public ErrorBase {
*/
void RemoveServer(llvm::StringRef name);
/**
* Get server for the primary camera feed.
*
* <p>This is only valid to call after a camera feed has been added
* with StartAutomaticCapture() or AddServer().
*/
cs::VideoSink GetServer();
/**
* Gets a server by name.
*
* @param name Server name
*/
cs::VideoSink GetServer(llvm::StringRef name);
/**
* Adds an already created camera.
*
@@ -277,6 +295,7 @@ class CameraServer : public ErrorBase {
static constexpr char const* kPublishName = "/CameraPublisher";
std::mutex m_mutex;
std::atomic<int> m_defaultUsbDevice;
std::string m_primarySourceName;
llvm::StringMap<cs::VideoSource> m_sources;
llvm::StringMap<cs::VideoSink> m_sinks;

View File

@@ -171,7 +171,7 @@ static std::string PixelFormatToString(int pixelFormat) {
return "Unknown";
}
}
#if 0
static cs::VideoMode::PixelFormat PixelFormatFromString(llvm::StringRef str) {
if (str == "MJPEG" || str == "mjpeg" || str == "JPEG" || str == "jpeg")
return cs::VideoMode::PixelFormat::kMJPEG;
@@ -228,7 +228,7 @@ static cs::VideoMode VideoModeFromString(llvm::StringRef modeStr) {
return mode;
}
#endif
static std::string VideoModeToString(const cs::VideoMode& mode) {
std::string rv;
llvm::raw_string_ostream oss{rv};
@@ -261,9 +261,9 @@ static void PutSourcePropertyValue(ITable* table, const cs::VideoEvent& event,
llvm::SmallString<64> infoName;
if (llvm::StringRef{event.name}.startswith("raw_")) {
name = "RawProperty/";
name += llvm::StringRef{event.name}.substr(4);
name += event.name;
infoName = "RawPropertyInfo/";
infoName += llvm::StringRef{event.name}.substr(4);
infoName += event.name;
} else {
name = "Property/";
name += event.name;
@@ -427,6 +427,9 @@ CameraServer::CameraServer()
0x4fff, true};
// Listener for NetworkTable events
// We don't currently support changing settings via NT due to
// synchronization issues, so just update to current setting if someone
// else tries to change it.
llvm::SmallString<64> buf;
m_tableListener = nt::AddEntryListener(
Concatenate(kPublishName, "/", buf),
@@ -446,24 +449,16 @@ CameraServer::CameraServer()
relativeKey = relativeKey.substr(subKeyIndex + 1);
// handle standard names
llvm::SmallString<64> propNameBuf;
llvm::StringRef propName;
if (relativeKey == "mode") {
if (!value->IsString()) return;
auto mode = VideoModeFromString(value->GetString());
if (mode.pixelFormat == cs::VideoMode::PixelFormat::kUnknown ||
!sourceIt->second.SetVideoMode(mode)) {
// reset to current mode
nt::SetEntryValue(key, nt::Value::MakeString(VideoModeToString(
sourceIt->second.GetVideoMode())));
}
// reset to current mode
nt::SetEntryValue(key, nt::Value::MakeString(VideoModeToString(
sourceIt->second.GetVideoMode())));
return;
} else if (relativeKey.startswith("Property/")) {
propName = relativeKey.substr(9);
} else if (relativeKey.startswith("RawProperty/")) {
propNameBuf = "raw_";
propNameBuf += relativeKey.substr(12);
propName = propNameBuf.str();
propName = relativeKey.substr(12);
} else {
return; // ignore
}
@@ -474,17 +469,14 @@ CameraServer::CameraServer()
case cs::VideoProperty::kNone:
return;
case cs::VideoProperty::kBoolean:
if (!value->IsBoolean()) return;
property.Set(value->GetBoolean() ? 1 : 0);
nt::SetEntryValue(key, nt::Value::MakeBoolean(property.Get() != 0));
return;
case cs::VideoProperty::kInteger:
case cs::VideoProperty::kEnum:
if (!value->IsDouble()) return;
property.Set(static_cast<int>(value->GetDouble()));
nt::SetEntryValue(key, nt::Value::MakeDouble(property.Get()));
return;
case cs::VideoProperty::kString:
if (!value->IsString()) return;
property.SetString(value->GetString());
nt::SetEntryValue(key, nt::Value::MakeString(property.GetString()));
return;
default:
return;
@@ -494,7 +486,7 @@ CameraServer::CameraServer()
}
cs::UsbCamera CameraServer::StartAutomaticCapture() {
return StartAutomaticCapture(0);
return StartAutomaticCapture(m_defaultUsbDevice++);
}
cs::UsbCamera CameraServer::StartAutomaticCapture(int dev) {
@@ -667,6 +659,33 @@ void CameraServer::RemoveServer(llvm::StringRef name) {
m_sinks.erase(name);
}
cs::VideoSink CameraServer::GetServer() {
llvm::SmallString<64> name;
{
std::lock_guard<std::mutex> lock(m_mutex);
if (m_primarySourceName.empty()) {
wpi_setWPIErrorWithContext(CameraServerError, "no camera available");
return cs::VideoSink{};
}
name = "serve_";
name += m_primarySourceName;
}
return GetServer(name);
}
cs::VideoSink CameraServer::GetServer(llvm::StringRef name) {
std::lock_guard<std::mutex> lock(m_mutex);
auto it = m_sinks.find(name);
if (it == m_sinks.end()) {
llvm::SmallString<64> buf;
llvm::raw_svector_ostream err{buf};
err << "could not find server " << name;
wpi_setWPIErrorWithContext(CameraServerError, err.str());
return cs::VideoSink{};
}
return it->second;
}
void CameraServer::AddCamera(const cs::VideoSource& camera) {
std::string name = camera.GetName();
std::lock_guard<std::mutex> lock(m_mutex);

View File

@@ -51,7 +51,7 @@ bool I2C::Transaction(uint8_t* dataToSend, int sendSize, uint8_t* dataReceived,
status = HAL_TransactionI2C(m_port, m_deviceAddress, dataToSend, sendSize,
dataReceived, receiveSize);
// wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return status < receiveSize;
return status < 0;
}
/**
@@ -81,7 +81,7 @@ bool I2C::Write(int registerAddress, uint8_t data) {
buffer[1] = data;
int32_t status = 0;
status = HAL_WriteI2C(m_port, m_deviceAddress, buffer, sizeof(buffer));
return status < static_cast<int>(sizeof(buffer));
return status < 0;
}
/**
@@ -97,7 +97,7 @@ bool I2C::Write(int registerAddress, uint8_t data) {
bool I2C::WriteBulk(uint8_t* data, int count) {
int32_t status = 0;
status = HAL_WriteI2C(m_port, m_deviceAddress, data, count);
return status < count;
return status < 0;
}
/**
@@ -122,8 +122,8 @@ bool I2C::Read(int registerAddress, int count, uint8_t* buffer) {
wpi_setWPIErrorWithContext(NullParameter, "buffer");
return true;
}
return Transaction(reinterpret_cast<uint8_t*>(&registerAddress),
sizeof(registerAddress), buffer, count);
uint8_t regAddr = registerAddress;
return Transaction(&regAddr, sizeof(regAddr), buffer, count);
}
/**
@@ -146,9 +146,7 @@ bool I2C::ReadOnly(int count, uint8_t* buffer) {
wpi_setWPIErrorWithContext(NullParameter, "buffer");
return true;
}
int32_t status = 0;
status = HAL_ReadI2C(m_port, m_deviceAddress, buffer, count);
return status < count;
return HAL_ReadI2C(m_port, m_deviceAddress, buffer, count) < 0;
}
/**

View File

@@ -140,14 +140,14 @@ RobotDrive::RobotDrive(std::shared_ptr<SpeedController> leftMotor,
*
* Speed controller input version of RobotDrive (see previous comments).
*
* @param rearLeftMotor The back left SpeedController object used to drive
* the robot.
* @param frontLeftMotor The front left SpeedController object used to drive
* the robot.
* @param rearRightMotor The back right SpeedController object used to drive
* @param rearLeftMotor The back left SpeedController object used to drive
* the robot.
* @param frontRightMotor The front right SpeedController object used to drive
* the robot.
* @param rearRightMotor The back right SpeedController object used to drive
* the robot.
*/
RobotDrive::RobotDrive(SpeedController* frontLeftMotor,
SpeedController* rearLeftMotor,

View File

@@ -12,6 +12,7 @@
#include "HAL/HAL.h"
#include "WPIErrors.h"
#include "llvm/SmallVector.h"
using namespace frc;
@@ -147,9 +148,9 @@ int SPI::Write(uint8_t* data, int size) {
int SPI::Read(bool initiate, uint8_t* dataReceived, int size) {
int retVal = 0;
if (initiate) {
auto dataToSend = new uint8_t[size];
std::memset(dataToSend, 0, size);
retVal = HAL_TransactionSPI(m_port, dataToSend, dataReceived, size);
llvm::SmallVector<uint8_t, 32> dataToSend;
dataToSend.resize(size);
retVal = HAL_TransactionSPI(m_port, dataToSend.data(), dataReceived, size);
} else {
retVal = HAL_ReadSPI(m_port, dataReceived, size);
}

View File

@@ -230,7 +230,6 @@ bool DriverStation::IsTest() const {
/**
* Is the driver station attached to a Field Management System?
* Note: This does not work with the Blue DS.
* @return True if the robot is competing on a field being controlled by a Field
* Management System
*/

View File

@@ -24,8 +24,9 @@ import edu.wpi.cscore.VideoSource;
import edu.wpi.first.wpilibj.networktables.NetworkTable;
import edu.wpi.first.wpilibj.networktables.NetworkTablesJNI;
import edu.wpi.first.wpilibj.tables.ITable;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -49,20 +50,21 @@ public class CameraServer {
/**
* Get the CameraServer instance.
*/
public static CameraServer getInstance() {
public static synchronized CameraServer getInstance() {
if (server == null) {
server = new CameraServer();
}
return server;
}
private AtomicInteger m_defaultUsbDevice;
private String m_primarySourceName;
private HashMap<String, VideoSource> m_sources;
private HashMap<String, VideoSink> m_sinks;
private HashMap<Integer, ITable> m_tables; // indexed by source handle
private ITable m_publishTable;
private VideoListener m_videoListener; //NOPMD
private int m_tableListener; //NOPMD
private final Hashtable<String, VideoSource> m_sources;
private final Hashtable<String, VideoSink> m_sinks;
private final Hashtable<Integer, ITable> m_tables; // indexed by source handle
private final ITable m_publishTable;
private final VideoListener m_videoListener; //NOPMD
private final int m_tableListener; //NOPMD
private int m_nextPort;
private String[] m_addresses;
@@ -93,11 +95,6 @@ public class CameraServer {
return "mjpg:http://" + address + ":" + port + "/?action=stream";
}
@SuppressWarnings("JavadocMethod")
private synchronized ITable getSourceTable(int source) {
return m_tables.get(source);
}
@SuppressWarnings({"JavadocMethod", "PMD.AvoidUsingHardCodedIP"})
private synchronized String[] getSinkStreamValues(int sink) {
// Ignore all but MjpegServer
@@ -290,8 +287,8 @@ public class CameraServer {
String name;
String infoName;
if (event.name.startsWith("raw_")) {
name = "RawProperty/" + event.name.substring(4);
infoName = "RawPropertyInfo/" + event.name.substring(4);
name = "RawProperty/" + event.name;
infoName = "RawPropertyInfo/" + event.name;
} else {
name = "Property/" + event.name;
infoName = "PropertyInfo/" + event.name;
@@ -335,9 +332,10 @@ public class CameraServer {
@SuppressWarnings({"JavadocMethod", "PMD.UnusedLocalVariable"})
private CameraServer() {
m_sources = new HashMap<String, VideoSource>();
m_sinks = new HashMap<String, VideoSink>();
m_tables = new HashMap<Integer, ITable>();
m_defaultUsbDevice = new AtomicInteger();
m_sources = new Hashtable<String, VideoSource>();
m_sinks = new Hashtable<String, VideoSink>();
m_tables = new Hashtable<Integer, ITable>();
m_publishTable = NetworkTable.getTable(kPublishName);
m_nextPort = kBasePort;
m_addresses = new String[0];
@@ -359,21 +357,23 @@ public class CameraServer {
case kSourceCreated: {
// Create subtable for the camera
ITable table = m_publishTable.getSubTable(event.name);
synchronized (this) {
m_tables.put(event.sourceHandle, table);
}
m_tables.put(event.sourceHandle, table);
table.putString("source", makeSourceValue(event.sourceHandle));
table.putString("description",
CameraServerJNI.getSourceDescription(event.sourceHandle));
table.putBoolean("connected", CameraServerJNI.isSourceConnected(event.sourceHandle));
table.putStringArray("streams", getSourceStreamValues(event.sourceHandle));
VideoMode mode = CameraServerJNI.getSourceVideoMode(event.sourceHandle);
table.setDefaultString("mode", videoModeToString(mode));
table.putStringArray("modes", getSourceModeValues(event.sourceHandle));
try {
VideoMode mode = CameraServerJNI.getSourceVideoMode(event.sourceHandle);
table.setDefaultString("mode", videoModeToString(mode));
table.putStringArray("modes", getSourceModeValues(event.sourceHandle));
} catch (VideoException ex) {
// Do nothing. Let the other event handlers update this if there is an error.
}
break;
}
case kSourceDestroyed: {
ITable table = getSourceTable(event.sourceHandle);
ITable table = m_tables.get(event.sourceHandle);
if (table != null) {
table.putString("source", "");
table.putStringArray("streams", new String[0]);
@@ -382,7 +382,7 @@ public class CameraServer {
break;
}
case kSourceConnected: {
ITable table = getSourceTable(event.sourceHandle);
ITable table = m_tables.get(event.sourceHandle);
if (table != null) {
// update the description too (as it may have changed)
table.putString("description",
@@ -392,42 +392,42 @@ public class CameraServer {
break;
}
case kSourceDisconnected: {
ITable table = getSourceTable(event.sourceHandle);
ITable table = m_tables.get(event.sourceHandle);
if (table != null) {
table.putBoolean("connected", false);
}
break;
}
case kSourceVideoModesUpdated: {
ITable table = getSourceTable(event.sourceHandle);
ITable table = m_tables.get(event.sourceHandle);
if (table != null) {
table.putStringArray("modes", getSourceModeValues(event.sourceHandle));
}
break;
}
case kSourceVideoModeChanged: {
ITable table = getSourceTable(event.sourceHandle);
ITable table = m_tables.get(event.sourceHandle);
if (table != null) {
table.putString("mode", videoModeToString(event.mode));
}
break;
}
case kSourcePropertyCreated: {
ITable table = getSourceTable(event.sourceHandle);
ITable table = m_tables.get(event.sourceHandle);
if (table != null) {
putSourcePropertyValue(table, event, true);
}
break;
}
case kSourcePropertyValueUpdated: {
ITable table = getSourceTable(event.sourceHandle);
ITable table = m_tables.get(event.sourceHandle);
if (table != null) {
putSourcePropertyValue(table, event, false);
}
break;
}
case kSourcePropertyChoicesUpdated: {
ITable table = getSourceTable(event.sourceHandle);
ITable table = m_tables.get(event.sourceHandle);
if (table != null) {
String[] choices = CameraServerJNI.getEnumPropertyChoices(event.propertyHandle);
table.putStringArray("PropertyInfo/" + event.name + "/choices", choices);
@@ -450,8 +450,11 @@ public class CameraServer {
}, 0x4fff, true);
// Listener for NetworkTable events
// We don't currently support changing settings via NT due to
// synchronization issues, so just update to current setting if someone
// else tries to change it.
m_tableListener = NetworkTablesJNI.addEntryListener(kPublishName + "/",
(uid, key, value, flags) -> {
(uid, key, eventValue, flags) -> {
String relativeKey = key.substring(kPublishName.length() + 1);
// get source (sourceName/...)
@@ -471,16 +474,13 @@ public class CameraServer {
// handle standard names
String propName;
if (relativeKey.equals("mode")) {
VideoMode mode = videoModeFromString((String) value);
if (mode.pixelFormat == PixelFormat.kUnknown || !source.setVideoMode(mode)) {
// reset to current mode
NetworkTablesJNI.putString(key, videoModeToString(source.getVideoMode()));
}
// reset to current mode
NetworkTablesJNI.putString(key, videoModeToString(source.getVideoMode()));
return;
} else if (relativeKey.startsWith("Property/")) {
propName = relativeKey.substring(9);
} else if (relativeKey.startsWith("RawProperty/")) {
propName = "raw_" + relativeKey.substring(12);
propName = relativeKey.substring(12);
} else {
return; // ignore
}
@@ -491,14 +491,17 @@ public class CameraServer {
case kNone:
return;
case kBoolean:
property.set(((Boolean) value).booleanValue() ? 1 : 0);
// reset to current setting
NetworkTablesJNI.putBoolean(key, property.get() != 0);
return;
case kInteger:
case kEnum:
property.set(((Double) value).intValue());
// reset to current setting
NetworkTablesJNI.putDouble(key, property.get());
return;
case kString:
property.setString((String) value);
// reset to current setting
NetworkTablesJNI.putString(key, property.getString());
return;
default:
return;
@@ -513,11 +516,13 @@ public class CameraServer {
* If you also want to perform vision processing on the roboRIO, use
* getVideo() to get access to the camera images.
*
* <p>This overload calls {@link #startAutomaticCapture(int)} with device 0,
* creating a camera named "USB Camera 0".
* <p>The first time this overload is called, it calls
* {@link #startAutomaticCapture(int)} with device 0, creating a camera
* named "USB Camera 0". Subsequent calls increment the device number
* (e.g. 1, 2, etc).
*/
public UsbCamera startAutomaticCapture() {
return startAutomaticCapture(0);
return startAutomaticCapture(m_defaultUsbDevice.getAndIncrement());
}
/**
@@ -745,6 +750,32 @@ public class CameraServer {
}
}
/**
* Get server for the primary camera feed.
*
* <p>This is only valid to call after a camera feed has been added
* with startAutomaticCapture() or addServer().
*/
public VideoSink getServer() {
synchronized (this) {
if (m_primarySourceName == null) {
throw new VideoException("no camera available");
}
return getServer("serve_" + m_primarySourceName);
}
}
/**
* Gets a server by name.
*
* @param name Server name
*/
public VideoSink getServer(String name) {
synchronized (this) {
return m_sinks.get(name);
}
}
/**
* Adds an already created camera.
*

View File

@@ -546,9 +546,9 @@ public class DriverStation implements RobotState.Interface {
return m_newControlData.getAndSet(false);
}
@SuppressWarnings({"SummaryJavadoc", "JavadocMethod"})
/**
* Is the driver station attached to a Field Management System? Note: This does not work with the
* Blue DS.
* Is the driver station attached to a Field Management System?
*
* @return True if the robot is competing on a field being controlled by a Field Management System
*/

View File

@@ -83,7 +83,7 @@ public class I2C extends SensorBase {
if (receiveSize > 0 && dataReceived != null) {
dataReceivedBuffer.get(dataReceived);
}
return status < receiveSize;
return status < 0;
}
/**
@@ -117,7 +117,7 @@ public class I2C extends SensorBase {
}
return I2CJNI.i2CTransaction((byte) m_port.value, (byte) m_deviceAddress, dataToSend,
(byte) sendSize, dataReceived, (byte) receiveSize) < receiveSize;
(byte) sendSize, dataReceived, (byte) receiveSize) < 0;
}
/**
@@ -139,6 +139,7 @@ public class I2C extends SensorBase {
*
* @param registerAddress The address of the register on the device to be written.
* @param data The byte to write to the register on the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
public synchronized boolean write(int registerAddress, int data) {
byte[] buffer = new byte[2];
@@ -149,7 +150,7 @@ public class I2C extends SensorBase {
dataToSendBuffer.put(buffer);
return I2CJNI.i2CWrite((byte) m_port.value, (byte) m_deviceAddress, dataToSendBuffer,
(byte) buffer.length) < buffer.length;
(byte) buffer.length) < 0;
}
/**
@@ -158,13 +159,14 @@ public class I2C extends SensorBase {
* <p>Write multiple bytes to a register on a device and wait until the transaction is complete.
*
* @param data The data to write to the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
public synchronized boolean writeBulk(byte[] data) {
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(data.length);
dataToSendBuffer.put(data);
return I2CJNI.i2CWrite((byte) m_port.value, (byte) m_deviceAddress, dataToSendBuffer,
(byte) data.length) < data.length;
(byte) data.length) < 0;
}
/**
@@ -173,6 +175,7 @@ public class I2C extends SensorBase {
* <p>Write multiple bytes to a register on a device and wait until the transaction is complete.
*
* @param data The data to write to the device. Must be created using ByteBuffer.allocateDirect().
* @return Transfer Aborted... false for success, true for aborted.
*/
public synchronized boolean writeBulk(ByteBuffer data, int size) {
if (!data.isDirect()) {
@@ -183,7 +186,7 @@ public class I2C extends SensorBase {
"buffer is too small, must be at least " + size);
}
return I2CJNI.i2CWrite((byte) m_port.value, (byte) m_deviceAddress, data, (byte) size) < size;
return I2CJNI.i2CWrite((byte) m_port.value, (byte) m_deviceAddress, data, (byte) size) < 0;
}
/**
@@ -264,7 +267,7 @@ public class I2C extends SensorBase {
int retVal = I2CJNI.i2CRead((byte) m_port.value, (byte) m_deviceAddress, dataReceivedBuffer,
(byte) count);
dataReceivedBuffer.get(buffer);
return retVal < count;
return retVal < 0;
}
/**
@@ -291,7 +294,7 @@ public class I2C extends SensorBase {
}
return I2CJNI.i2CRead((byte) m_port.value, (byte) m_deviceAddress, buffer, (byte) count)
< count;
< 0;
}
/*

View File

@@ -128,10 +128,10 @@ public class RobotDrive implements MotorSafety {
* Constructor for RobotDrive with 4 motors specified as SpeedController objects. Speed controller
* input version of RobotDrive (see previous comments).
*
* @param rearLeftMotor The back left SpeedController object used to drive the robot.
* @param frontLeftMotor The front left SpeedController object used to drive the robot
* @param rearRightMotor The back right SpeedController object used to drive the robot.
* @param rearLeftMotor The back left SpeedController object used to drive the robot.
* @param frontRightMotor The front right SpeedController object used to drive the robot.
* @param rearRightMotor The back right SpeedController object used to drive the robot.
*/
public RobotDrive(SpeedController frontLeftMotor, SpeedController rearLeftMotor,
SpeedController frontRightMotor, SpeedController rearRightMotor) {

View File

@@ -74,7 +74,7 @@ public class SafePWM extends PWM implements MotorSafety {
/**
* Feed the MotorSafety timer. This method is called by the subclass motor whenever it updates its
* speed, thereby reseting the timeout value.
* speed, thereby resetting the timeout value.
*/
@SuppressWarnings("MethodName")
public void Feed() {

View File

@@ -727,7 +727,7 @@ public class PIDController implements PIDInterface, LiveWindowSendable, Controll
setSetpoint((Double) value);
}
} else if (key.equals("enabled")) {
if (isEnable() != (Boolean) value) {
if (isEnabled() != (Boolean) value) {
if ((Boolean) value) {
enable();
} else {
@@ -750,7 +750,7 @@ public class PIDController implements PIDInterface, LiveWindowSendable, Controll
table.putNumber("d", getD());
table.putNumber("f", getF());
table.putNumber("setpoint", getSetpoint());
table.putBoolean("enabled", isEnable());
table.putBoolean("enabled", isEnabled());
table.addTableListener(m_listener, false);
}
}

View File

@@ -335,8 +335,7 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Is the driver station attached to a Field Management System? Note: This does not work with the
* Blue DS.
* Is the driver station attached to a Field Management System?
*
* @return True if the robot is competing on a field being controlled by a Field Management System
*/