1

hide 2 posts

This commit is contained in:
Evan Pratten 2020-01-19 21:05:52 -05:00
parent ad3ee291a0
commit cafb70eb0a
No known key found for this signature in database
GPG Key ID: 93AC7B3D071356D3
7 changed files with 175 additions and 0 deletions

View File

@ -0,0 +1,54 @@
---
layout: post
title: "Graphical drivebase simulation for FRC robots"
description: "Showcasing part of the frc5024 codebase"
date: 2020-01-07 22:13:00
categories: frc
redirect_from:
- /post/vcv4101s90/
- /vcv4101s90/
---
The 2020 FRC season has kicked off, and the @frc5024 software team is already hard at work developing the software that will power this year's robot. Throughout the season, I'm hoping to showcase cool things we work on.
Today, I built a little tool to provide a graphical simulation of our robot's drivebase in 2D space. This post will outline how I did it.
## Robot simulation
As our code is developed with [WPILib](https://github.com/wpilibsuite/allwpilib), we make use of [HALSIM](https://github.com/wpilibsuite/allwpilib/tree/master/simulation/halsim_gui) to test out code before pushing to real hardware. This tool is great for checking for null pointer exceptions, and ensuring telemetry data is correctly pushed, but has some limitations. Mainly, we use a fair amount of un-supported hardware, and our own robotics library does not integrate with WPILib's "Sendable" system.
### Faking HAL device support
To give HALSIM support to our custom devices, we use WPILib's [SimDevice](https://github.com/wpilibsuite/allwpilib/blob/master/hal/src/main/java/edu/wpi/first/hal/SimDevice.java) wrapper. @PeterJohnson explained to me how to do this [in this thread](https://www.chiefdelphi.com/t/ctre-halsim/370106/2?u=ewpratten).
### Simulating sensors
For drivebase simulation, we need to simulate two devices. Our [encoders](https://www.usdigital.com/products/encoders/incremental/kit/E4T), and our [gyroscope](https://pdocs.kauailabs.com/navx-mxp/). Neither of these devices have HALSIM support, so I added my own [[1](https://github.com/frc5024/InfiniteRecharge/commit/837e9f571a03917c72b2df83d4e19650bab4ad66)] [[2](https://github.com/frc5024/InfiniteRecharge/commit/78c501a4bbaeee1d05e95a3c1ba07a897bc78a80)].
Now that the device I/O has been simulated, we need to simulate sensor readings.
#### Encoders
Encoder readings can be estimated, assuming we know these properties:
- Current motor speed (percent output)
- Max motor speed (RPM)
- Encoder Pulses per Revolution
- Gearing ratio between simulated motor and sensor
Inside a quickly-updating loop, I used this pseudocode to determine the reading for an encoder:
```java
double current_time = getSeconds();
double dt = current_time - last_time;
last_time = current_time;
double rpm = (getMotorSpeed() * max_rpm) / gearbox_ratio;
double revs = (rpm / 60.0) * dt;
encoder_ticks += (revs * tpr);
```
#### Gyroscope

View File

@ -0,0 +1,89 @@
---
layout: post
title: "Interpolating motor control commands from Dart data"
description: "And other weird things to do with XY datasets"
date: 2020-01-14 20:13:00
categories: frc data
redirect_from:
- /post/eb3v140d/
- /eb3v140d/
---
At some FRC events, [ZEBRA Technologies](https://www.zebra.com/us/en.html) places dart trackers for their [MotionWorks](https://www.zebra.com/us/en/solutions/intelligent-edge-solutions/rtls.html) system on robots. They then provide real-time motion tracking data for all bots on the field. I got my hands on a few data archives from various events in 2019 that used the darts. Here is a little post about what I have been able to do with this data.
## The data
For this post, I will be working with data from [Chezy Champs 2019](https://chezychamps.com/). I recived the tracking data in the following CSV format:
```csv
X position (Feet), Y position (Feet), UNIX epoch time (UTC)
```
## Data analysis
I wrote a little parser that converts the CSV data to pose data. A pose is a vector containing the following field-absolute components:
```c++
struct Pose {
double x;
double y;
double theta;
}
```
While we are at it, Ill define a "Transpose", which is like a pose, but relative to other poses, and a "ChassisSpeed" vector:
```c++
struct ChassisSpeed {
double left;
double right;
}
class Transpose {
private:
double x;
double y;
double theta;
public:
ChassisSpeed fromTranspose();
}
```
### Converting a difference to a Transpose
The only data we can directly read from the Dart data is poses over time (all poses have an angle of 0 degrees). To convert these to Transposes, we need to do a little math. Basically, we can take two poses, then calculate their differences:
```python
# Find the differences in coords
dx: float = now.x - last.x
dy: float = now.y - last.y
# Calculate a heading from translation
theta: float = atan2(dx, dy)
```
Now, with this data, we can build a Transpose out of any pair of data points.
### Converting a transpose to a ChassisSpeed
To be completely honest, I originally had no idea what I was going to use this data for, but ended up deciding to try to reconstruct motor data from the position data. This is just a form of [Inverse Kinematics](https://en.wikipedia.org/wiki/Inverse_kinematics).
To do this, all we need is a little math:
```java
ChassisSpeed fromTranspose(){
double delta = TRACK_WIDTH * this.theta / 2 * 1.0469745223;
return (new ChassisSpeed(this.x - deltaV, this.x + deltaV);
}
```
This will calculate the heading difference between 0,0 and the transpose, then apply that to the X vector as a wheel velocity. `TRACK_WIDTH` is the width of the robot drivebase in inches (I used `25.4` because that is team [254](https://www.thebluealliance.com/team/254)'s track width)
#### Chassis speeds over time
Here is a little graph of the calculated chassis speeds over time. (Keeping in mind that inaccuracies in the Dart system cause some "drift")
![Chassis Speeds](/assets/images/chassis-speeds.png)
### Extrapolating further

32
_drafts/Untitled-1 Normal file
View File

@ -0,0 +1,32 @@
00000000
01000000
00000001
10001000
00001100
00000010
0x4001880C02
00000000
01000000
00000000
10000000
00000100
00000010
00000000
01001011
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000100
00001101
00000100
01110111
00000000
00000011
!'gO7"9JQrz!!!!%%0UkT!r

0
_includes/advert.html Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB