use of com.qualcomm.robotcore.exception.RobotCoreException in project robotcode by OutoftheBoxFTC.
the class HardwareDeviceManager method scanForUsbDevices.
// ------------------------------------------------------------------------------------------------
// Scanning
// ------------------------------------------------------------------------------------------------
/* (non-Javadoc)
* @see com.qualcomm.hardware.DeviceManager#scanForUsbDevices()
*
* Returns a map from serial number to DeviceType
*/
@Override
public Map<SerialNumber, DeviceType> scanForUsbDevices() throws RobotCoreException {
synchronized (scanDevicesLock) {
long start = System.nanoTime();
final Map<SerialNumber, DeviceType> deviceMap = new ConcurrentHashMap<SerialNumber, DeviceType>();
int devCount = usbManager.scanForDevices();
RobotLog.vv(TAG_USB_SCAN, "device count=%d", devCount);
if (devCount > 0) {
// Open all the USB devices attached to the robot controller. We do this in parallel so as to minimize latency to the user.
ExecutorService executorService = ThreadPool.newFixedThreadPool(devCount, "hw mgr usb scan");
final ConcurrentHashMap<SerialNumber, RobotUsbDevice> newlyFoundDevices = new ConcurrentHashMap<SerialNumber, RobotUsbDevice>();
try {
for (int id = 0; id < devCount; id++) {
final SerialNumber serialNumber = usbManager.getDeviceSerialNumberByIndex(id);
executorService.execute(new Runnable() {
@Override
public void run() {
try {
RobotLog.vv(TAG_USB_SCAN, "opening %s...", serialNumber);
//
// It turns out that ModernRoboticsUsbUtil.openUsbDevice doesn't contain any
// logic that is specific to ModernRobotics, but rather is generic, and so
// can be used even on Lynx devices
RobotUsbDevice device = ModernRoboticsUsbUtil.openUsbDevice(false, usbManager, serialNumber);
newlyFoundDevices.put(serialNumber, device);
//
} catch (Exception e) {
RobotLog.vv(TAG_USB_SCAN, "%s(%s) exception while opening %s", e.getClass().getSimpleName(), e.getMessage(), serialNumber.toString());
} finally {
RobotLog.vv(TAG_USB_SCAN, "... done opening %s", serialNumber);
}
}
});
}
// Wait for all those opens to finish
executorService.shutdown();
ThreadPool.awaitTerminationOrExitApplication(executorService, 30, TimeUnit.SECONDS, "USB Scanning Service", "internal error");
// Having opened everything, determine the type of each
for (Map.Entry<SerialNumber, RobotUsbDevice> pair : newlyFoundDevices.entrySet()) {
determineDeviceType(pair.getValue(), pair.getKey(), deviceMap);
}
// Also consider devices that are already open
for (RobotUsbDevice existingDevice : RobotUsbDeviceImplBase.getExtantDevices()) {
SerialNumber serialNumber = existingDevice.getSerialNumber();
if (!newlyFoundDevices.containsKey(serialNumber)) {
DeviceType deviceType = existingDevice.getDeviceType();
if (deviceType != DeviceType.FTDI_USB_UNKNOWN_DEVICE) {
RobotLog.vv(TAG_USB_SCAN, "added extant device %s type=%s", serialNumber.toString(), deviceType.toString());
deviceMap.put(serialNumber, deviceType);
}
}
}
} finally {
// On the way out, be sure to close all.
for (Map.Entry<SerialNumber, RobotUsbDevice> pair : newlyFoundDevices.entrySet()) {
RobotLog.vv(TAG_USB_SCAN, "closing %s", pair.getKey());
pair.getValue().close();
}
}
}
long end = System.nanoTime();
RobotLog.vv(TAG_USB_SCAN, "scanForUsbDevices() took %dms count=%d", (int) ((end - start) / ElapsedTime.MILLIS_IN_NANO), deviceMap.size());
return deviceMap;
}
}
use of com.qualcomm.robotcore.exception.RobotCoreException in project robotcode by OutoftheBoxFTC.
the class HardwareDeviceManager method createLynxUsbDevice.
// ------------------------------------------------------------------------------------------------
// Creation
// ------------------------------------------------------------------------------------------------
/**
* Note: unlike other creation methods, creating a Lynx USB device will succeed even if
* the device is already open (in which case it will return a new delegate to the existing
* instance).
*/
@Override
public RobotCoreLynxUsbDevice createLynxUsbDevice(final SerialNumber serialNumber, String name) throws RobotCoreException, InterruptedException {
HardwareFactory.noteSerialNumberType(context, serialNumber, context.getString(R.string.moduleDisplayNameLynxUsbDevice));
RobotLog.v("Creating %s", HardwareFactory.getDeviceDisplayName(context, serialNumber));
ModernRoboticsUsbDevice.OpenRobotUsbDevice openRobotUsbDevice = new ModernRoboticsUsbDevice.OpenRobotUsbDevice() {
@Override
public RobotUsbDevice open() throws RobotCoreException, InterruptedException {
RobotUsbDevice dev = null;
try {
dev = LynxUsbUtil.openUsbDevice(usbManager, serialNumber);
if (!dev.getUsbIdentifiers().isLynxDevice()) {
closeAndThrowOnFailedDeviceTypeCheck(dev, serialNumber);
}
DeviceType type = getLynxDeviceType(dev);
Assert.assertTrue(type == DeviceType.LYNX_USB_DEVICE);
} catch (RobotCoreException | RuntimeException e) {
if (dev != null) {
// avoid leakage of open FT_Devices
dev.close();
}
throw e;
}
return dev;
}
};
return LynxUsbDeviceImpl.findOrCreateAndArm(context, serialNumber, manager, openRobotUsbDevice);
}
use of com.qualcomm.robotcore.exception.RobotCoreException in project robotcode by OutoftheBoxFTC.
the class HardwareDeviceManager method createDeviceInterfaceModule.
@Override
public DeviceInterfaceModule createDeviceInterfaceModule(final SerialNumber serialNumber, String name) throws RobotCoreException, InterruptedException {
HardwareFactory.noteSerialNumberType(context, serialNumber, context.getString(R.string.moduleDisplayNameCDIM));
RobotLog.v("Creating %s", HardwareFactory.getDeviceDisplayName(context, serialNumber));
ModernRoboticsUsbDevice.OpenRobotUsbDevice openRobotUsbDevice = new ModernRoboticsUsbDevice.OpenRobotUsbDevice() {
@Override
public RobotUsbDevice open() throws RobotCoreException, InterruptedException {
RobotUsbDevice dev = null;
try {
dev = ModernRoboticsUsbUtil.openUsbDevice(true, usbManager, serialNumber);
byte[] deviceHeader = getModernRoboticsDeviceHeader(dev);
DeviceType type = getModernRoboticsDeviceType(dev, deviceHeader);
if (type != DeviceType.MODERN_ROBOTICS_USB_DEVICE_INTERFACE_MODULE) {
closeAndThrowOnFailedDeviceTypeCheck(dev, serialNumber);
}
dev.setFirmwareVersion(getModernRoboticsFirmwareVersion(deviceHeader));
} catch (RobotCoreException e) {
if (dev != null) {
// avoid leakage of open FT_Devices
dev.close();
}
throw e;
} catch (RuntimeException e) {
if (dev != null) {
// avoid leakage of open FT_Devices
dev.close();
}
throw e;
}
return dev;
}
};
ModernRoboticsUsbDeviceInterfaceModule deviceInterfaceModule = new ModernRoboticsUsbDeviceInterfaceModule(context, serialNumber, openRobotUsbDevice, manager);
deviceInterfaceModule.armOrPretend();
deviceInterfaceModule.initializeHardware();
return deviceInterfaceModule;
}
use of com.qualcomm.robotcore.exception.RobotCoreException in project robotcode by OutoftheBoxFTC.
the class HardwareFactory method mapLynxUsbDevice.
private void mapLynxUsbDevice(HardwareMap map, DeviceManager deviceMgr, LynxUsbDeviceConfiguration lynxUsbDeviceConfiguration) throws RobotCoreException, InterruptedException {
if (!lynxUsbDeviceConfiguration.isEnabled()) {
return;
}
// Make a new LynxUsbDevice
LynxUsbDevice lynxUsbDevice = (LynxUsbDevice) deviceMgr.createLynxUsbDevice(lynxUsbDeviceConfiguration.getSerialNumber(), lynxUsbDeviceConfiguration.getName());
try {
// If the system made up this device, let the live device know that too
if (lynxUsbDeviceConfiguration.isSystemSynthetic()) {
lynxUsbDevice.setSystemSynthetic(true);
}
// Are we the first USB-attached (as opposed to embedded) LynxUsbDevice?
boolean isFirstLynxUsbDevice = !LynxConstants.isEmbeddedSerialNumber(lynxUsbDeviceConfiguration.getSerialNumber());
for (LynxUsbDevice usbDevice : map.getAll(LynxUsbDevice.class)) {
if (!LynxConstants.isEmbeddedSerialNumber(usbDevice.getSerialNumber())) {
isFirstLynxUsbDevice = false;
break;
}
}
// Make all the modules first, since we need to ping the parent before pinging anyone else,
// and so we need to figure out who that is.
//
List<LynxModule> potentialModules = new ArrayList<LynxModule>();
Map<Integer, String> moduleNames = new HashMap<Integer, String>();
final int parentModuleAddress = lynxUsbDeviceConfiguration.getParentModuleAddress();
for (DeviceConfiguration moduleConfiguration : lynxUsbDeviceConfiguration.getModules()) {
int moduleAddress = moduleConfiguration.getPort();
moduleNames.put(moduleAddress, moduleConfiguration.getName());
//
LynxModule module = (LynxModule) deviceMgr.createLynxModule(lynxUsbDevice, moduleAddress, parentModuleAddress == moduleAddress, moduleConfiguration.getName());
potentialModules.add(module);
// If the system made up this device, let the live device know that too
if (((LynxModuleConfiguration) moduleConfiguration).isSystemSynthetic()) {
module.setSystemSynthetic(true);
}
}
// Attach all the LynxModules to that LynxUsbDevice, parents first, so that parents get pinged first. Note that if some
// modules aren't actually there, or are there but are wedged, these may throw exceptions.
Map<Integer, LynxModule> connectedModules = new HashMap<Integer, LynxModule>();
for (LynxModule module : potentialModules) {
if (module.isParent()) {
// nb: there should be only one parent
connectModule(lynxUsbDevice, module, moduleNames, connectedModules, isFirstLynxUsbDevice && connectedModules.isEmpty());
}
}
for (LynxModule module : potentialModules) {
if (!module.isParent()) {
connectModule(lynxUsbDevice, module, moduleNames, connectedModules, false);
}
}
// Finish adding all the pieces to the modules we successfully talked to
mapLynxModuleComponents(map, deviceMgr, lynxUsbDeviceConfiguration, lynxUsbDevice, connectedModules);
// For the things that worked, remember the module names in the hwmap
for (Map.Entry<Integer, LynxModule> pair : connectedModules.entrySet()) {
int moduleAddress = pair.getKey();
map.put(moduleNames.get(moduleAddress), pair.getValue());
}
// Remember the LynxUsbDevice too, so we we'll only enable one to charge the RC battery
map.put(lynxUsbDeviceConfiguration.getName(), lynxUsbDevice);
} catch (LynxNackException e) {
throw e.wrap();
} catch (RobotCoreException | RuntimeException e) {
lynxUsbDevice.close();
map.remove(lynxUsbDeviceConfiguration.getName(), lynxUsbDevice);
throw e;
}
}
use of com.qualcomm.robotcore.exception.RobotCoreException in project robotcode by OutoftheBoxFTC.
the class LynxI2cDeviceSynchV2 method readTimeStamped.
/*
* Supporting firmware version XX.XX.XX
*/
@Override
public synchronized TimestampedData readTimeStamped(final int ireg, final int creg) {
LynxI2cDeviceSynchV2 deviceHavingProblems = null;
boolean reportUnhealthy;
try {
return acquireI2cLockWhile(new Supplier<TimestampedData>() {
@Override
public TimestampedData get() throws InterruptedException, RobotCoreException, LynxNackException {
LynxCommand<?> tx = new LynxI2cWriteReadMultipleBytesCommand(getModule(), bus, i2cAddr, ireg, creg);
tx.send();
readTimeStampedPlaceholder.reset();
return pollForReadResult(i2cAddr, ireg, creg);
}
});
} catch (InterruptedException | RobotCoreException | RuntimeException e) {
handleException(e);
} catch (LynxNackException e) {
/*
* This is a possible device problem, go ahead and tell makeFakeData to warn.
*/
deviceHavingProblems = this;
handleException(e);
}
return readTimeStampedPlaceholder.log(TimestampedI2cData.makeFakeData(deviceHavingProblems, getI2cAddress(), ireg, creg));
}
Aggregations