Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sensor-based Navigation #42

Open
wants to merge 48 commits into
base: dev
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
94281bc
Complete raw sensor integration -> result: inaccurate
smo-key Jan 4, 2016
662e150
Add navX library
smo-key Jan 8, 2016
e806f16
Add a basic NavX device - now to add PID controller overrides
smo-key Jan 8, 2016
28ded79
Comment a thing or two
smo-key Jan 8, 2016
9976086
Start sensor test
smo-key Jan 8, 2016
fa289ae
Add collision detection
smo-key Jan 9, 2016
996849c
Add PID controller
smo-key Jan 9, 2016
d309ed2
Add idea for a navigator
smo-key Jan 9, 2016
d7dcdf2
Write a matrix implementation
smo-key Jan 9, 2016
3ed6f7b
Start Kalman filter implementation
smo-key Jan 9, 2016
afb4c96
Test a robot and confirm PID!
smo-key Jan 9, 2016
efc92f1
Add antistall protection
smo-key Jan 10, 2016
bb74002
Do a lot... for Navigator, try using encoders first
smo-key Jan 10, 2016
d48a758
Fix encoder class
smo-key Jan 10, 2016
ac70dbb
Start encoder improvements
smo-key Jan 10, 2016
81ea0f7
Write enocder distance API
smo-key Jan 10, 2016
8faf2b0
[INCOMPLETE] Start PID measurement
smo-key Jan 10, 2016
3674b7d
Complete PID loop structure
smo-key Jan 10, 2016
0bf2860
Complete a successful PID test! Next: tolerance and antistall
smo-key Jan 10, 2016
85dd25a
Simplify motor information and add future drivetrain config class
smo-key Jan 10, 2016
b3d65c9
Start testing... potential problem with part of new PID functionality
smo-key Jan 11, 2016
7d41b23
Attempt better Encoder Test code
smo-key Jan 11, 2016
1573c17
Start update
smo-key Jan 11, 2016
003eaec
Updates
smo-key Jan 16, 2016
901f7bc
Pre-smart-turning update
smo-key Jan 21, 2016
4e670ca
Complete VERY ACCURATE rotation
smo-key Jan 21, 2016
191f841
Upload directional motion upgrade
smo-key Jan 21, 2016
96f104f
Merge branch 'dev' into feature-nav
smo-key Jan 26, 2016
82a16ef
Add encoder test
smo-key Feb 13, 2016
b5e151e
Merge in stable RC upgrade
smo-key Feb 13, 2016
b932e8c
Add a test teleop
smo-key Feb 13, 2016
35ecd33
Prevent gamepad connection from throwing NullPointerException
smo-key Feb 15, 2016
477db7c
Successful auto-correcting drive!
smo-key Feb 15, 2016
3b1a32d
[UNTESTED] PID acceleration implementation
smo-key Feb 15, 2016
b71bc5c
Improvements?
smo-key Mar 17, 2016
f846443
Merge in dev
smo-key Mar 17, 2016
69d809f
Merge branch 'dev' into feature-nav
smo-key Mar 17, 2016
be51e27
PID loop tuning
smo-key Mar 17, 2016
f3a9eac
PID loop tuning
smo-key Mar 17, 2016
6410300
Revert PID loop tuning
smo-key Mar 17, 2016
97cfe47
AutoTuner that may work... probably not
BrendanHollaway Mar 17, 2016
8a0cd26
Auto tune PID thing that will probably blow up everything
BrendanHollaway Mar 17, 2016
1b6bcc2
Merge branch 'feature-nav' of https://github.com/lasarobotics/FTCLibr…
BrendanHollaway Mar 17, 2016
c937645
AutoTuner that may work... probably not v2
BrendanHollaway Mar 17, 2016
7edd142
WARNING! THIS CODE IS HIGHLY EXPLOSIVE. :boom:
smo-key Mar 17, 2016
96bd21f
Write simple NavX rotation nav lib
smo-key Apr 1, 2016
f3dac7d
Write advanced navigator
smo-key Apr 5, 2016
76a32c5
Add Nav improvements
smo-key Apr 7, 2016
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
Prev Previous commit
Next Next commit
Add collision detection
smo-key committed Jan 9, 2016
commit fa289aecb3ed99e7d313c0fff6f6def73ce76630
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.lasarobotics.library.sensor.kauailabs.navx;

/**
* Data receiver for the navX, allowing customized actions to be performed upon receiving data
*/
public interface NavXDataReceiver {
void dataReceived(long timeDelta);
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
package com.lasarobotics.library.sensor.kauailabs.navx;

import com.kauailabs.navx.ftc.AHRS;
import com.kauailabs.navx.ftc.IDataArrivalSubscriber;
import com.lasarobotics.library.util.Vector3;
import com.qualcomm.robotcore.hardware.HardwareMap;
import com.qualcomm.robotcore.robocol.Telemetry;

import java.security.InvalidParameterException;
import java.text.DecimalFormat;

/**
* NavX MXP controller
*/
public class NavXDevice {
public class NavXDevice implements IDataArrivalSubscriber {

static final DataType dataType = DataType.RAW_AND_PROCESSED;
static final int MAX_NUM_CALLBACKS = 3;
AHRS ahrs;
DataType dataType;
double last_world_linear_accel_x = 0.0;
double last_world_linear_accel_y = 0.0;
private double maxJerk = 0.0;
private long last_system_timestamp = 0;
private long last_sensor_timestamp = 0;
private double collisionThreshold = 0.5;
private NavXDataReceiver[] callbacks;

/**
* Initialize a NavX MXP or NavX micro device
@@ -23,7 +33,7 @@ public class NavXDevice {
* @param i2cPort The i2C port the sensor is currently on
*/
public NavXDevice(HardwareMap map, String deviceInterfaceModuleName, int i2cPort) {
initialize(map, deviceInterfaceModuleName, i2cPort, SensorSpeed.NORMAL_FAST, DataType.PROCESSED_DATA);
initialize(map, deviceInterfaceModuleName, i2cPort, SensorSpeed.NORMAL_FAST, dataType);
}

/**
@@ -41,7 +51,8 @@ public NavXDevice(HardwareMap map, String deviceInterfaceModuleName, int i2cPort
private void initialize(HardwareMap map, String deviceInterfaceModuleName, int i2cPort, SensorSpeed speed, DataType type) {
ahrs = AHRS.getInstance(map.deviceInterfaceModule.get(deviceInterfaceModuleName),
i2cPort, DataType.PROCESSED_DATA.getValue(), speed.getSpeedHertzByte());
this.dataType = type;
this.callbacks = new NavXDataReceiver[MAX_NUM_CALLBACKS];
ahrs.registerCallback(this);
}

public boolean isCalibrating() {
@@ -162,6 +173,126 @@ public float getHeading() {

public void stop() {
ahrs.close();
for (int i = 0; i < callbacks.length; i++) {
callbacks[i] = null;
}
}

public double getCollisionThreshold() {
return collisionThreshold;
}

public void setCollisionThreshold(double thresholdGs) {
if (thresholdGs <= 0.0)
throw new InvalidParameterException("Threshold must be greater than 0 Gs!");
this.collisionThreshold = thresholdGs;
}

/**
* Test whether the robot has collided - using the set or default threshold
*
* @return True if collided, false otherwise
*/
public boolean hasCollided() {
if (collisionThreshold <= 0.0)
throw new InvalidParameterException("Threshold must be greater than 0 Gs!");
return maxJerk > collisionThreshold;
}

/**
* Test whether the robot has collided
*
* @param thresholdGs Threshold for collision, in Gs. Default is 0.5 Gs.
* @return True if collided, false otherwise
*/
public boolean hasCollided(double thresholdGs) {
if (thresholdGs <= 0.0)
throw new InvalidParameterException("Threshold must be greater than 0 Gs!");
return maxJerk > thresholdGs;
}

/**
* Get the instantaneous jerk, in m/s^3.
*
* @return Jerk (derivative of acceleration, i.e. change in acceleration) in m/s^3.
*/
public double getJerk() {
return maxJerk;
}

/**
* Registers a callback interface. This interface
* will be called back when new data is available,
* based upon a change in the sensor timestamp.
* <p/>
* Note that this callback will occur within the context of the
* device IO thread, which is not the same thread context the
* caller typically executes in.
*/
public boolean registerCallback(NavXDataReceiver callback) {
boolean registered = false;
for (int i = 0; i < this.callbacks.length; i++) {
if (this.callbacks[i] == null) {
this.callbacks[i] = callback;
registered = true;
break;
}
}
return registered;
}

/**
* Deregisters a previously registered callback interface.
* <p/>
* Be sure to deregister any callback which have been
* previously registered, to ensure that the object
* implementing the callback interface does not continue
* to be accessed when no longer necessary.
*/
public boolean deregisterCallback(NavXDataReceiver callback) {
boolean deregistered = false;
for (int i = 0; i < this.callbacks.length; i++) {
if (this.callbacks[i] == callback) {
this.callbacks[i] = null;
deregistered = true;
break;
}
}
return deregistered;
}

@Override
public void untimestampedDataReceived(long curr_system_timestamp, Object kind) {
long system_timestamp_delta = curr_system_timestamp - last_system_timestamp;
for (NavXDataReceiver callback : callbacks) {
if (callback != null) {
callback.dataReceived(system_timestamp_delta);
}
}
}

@Override
public void timestampedDataReceived(long curr_system_timestamp, long curr_sensor_timestamp, Object kind) {
//Test for collisions
long sensor_timestamp_delta = curr_sensor_timestamp - last_sensor_timestamp;
long system_timestamp_delta = curr_system_timestamp - last_system_timestamp;
double curr_world_linear_accel_x = ahrs.getWorldLinearAccelX();
double currentJerkX = curr_world_linear_accel_x - last_world_linear_accel_x;
last_world_linear_accel_x = curr_world_linear_accel_x;
double curr_world_linear_accel_y = ahrs.getWorldLinearAccelY();
double currentJerkY = curr_world_linear_accel_y - last_world_linear_accel_y;
last_world_linear_accel_y = curr_world_linear_accel_y;

maxJerk = Math.max(Math.abs(currentJerkX), Math.abs(currentJerkY));

last_sensor_timestamp = curr_sensor_timestamp;
last_system_timestamp = curr_system_timestamp;

for (NavXDataReceiver callback : callbacks) {
if (callback != null) {
callback.dataReceived(sensor_timestamp_delta);
}
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.lasarobotics.library.sensor.kauailabs.navx;

/**
* PID Controller designed for the navX MXP or micro
*/
public class NavXPIDController {

}
1 change: 0 additions & 1 deletion sample/build.gradle
Original file line number Diff line number Diff line change
@@ -29,5 +29,4 @@ dependencies {
compile(name: 'Analytics-release', ext: 'aar')
compile(name: 'WirelessP2p-release', ext: 'aar')
compile project(':ftc-library')
compile project(':lib-navx')
}
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

import com.lasarobotics.library.controller.Controller;
import com.lasarobotics.library.drive.Tank;
import com.lasarobotics.library.sensor.kauailabs.navx.NavXDataReceiver;
import com.lasarobotics.library.sensor.kauailabs.navx.NavXDevice;
import com.qualcomm.robotcore.eventloop.opmode.OpMode;
import com.qualcomm.robotcore.hardware.DcMotor;
@@ -10,7 +11,10 @@
* OpMode designed to test extended functionality of the NavX sensor
* Requires four motors to test PID
*/
public class NavXSensorTest extends OpMode {
public class NavXSensorTest extends OpMode implements NavXDataReceiver {

final String NAVX_DIM = "dim"; //device interface module name
final int NAVX_PORT = 1; //port on device interface module

DcMotor frontLeft, frontRight, backLeft, backRight;
Controller one;
@@ -23,23 +27,32 @@ public void init() {
backRight = hardwareMap.dcMotor.get("backRight");

one = new Controller(gamepad1);
navx = new NavXDevice(hardwareMap, "dim", 1);

//Initialize the navX controller
//Make sure to implement NavXDataReceiver
navx = new NavXDevice(hardwareMap, NAVX_DIM, NAVX_PORT);
navx.registerCallback(this);
}

@Override
public void init_loop() {
public void start() {
navx.reset();
}

public void loop() {
one.update(gamepad1);
navx.displayTelemetry(telemetry);


Tank.motor4(frontLeft, frontRight, backLeft, backRight, one.left_stick_y, one.right_stick_y);
}

public void stop() {
navx.stop();
}

@Override
public void dataReceived(long timeDelta) {
telemetry.addData("NavX Collision", navx.hasCollided() ? "COLLIDED!" : "No collision");
telemetry.addData("NavX Jerk", navx.getJerk());
}
}