-
Notifications
You must be signed in to change notification settings - Fork 288
Advanced Controls Revamp #1821
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
Merged
Merged
Advanced Controls Revamp #1821
Changes from all commits
Commits
Show all changes
87 commits
Select commit
Hold shift + click to select a range
0b91bab
wip adding area for interactive walkthroughs
gerth2 a7e610a
WIP adding javascript to plot things
gerth2 0ec8297
more WIP getting interactive examples working
gerth2 aae9cc7
changed to light colors, added button controls
gerth2 d3eef6f
reorg and taking a few notes from the discord conversation
gerth2 08f23f4
reworked controls to be text entry. Added flywheel visualization.
gerth2 77b83b7
added time indication and other bug cleanup
gerth2 a54b1ed
ball injection checkbox
gerth2 d885fe9
wip, more words
gerth2 c550644
Update source/docs/software/advanced-controls/introduction/approaches…
gerth2 262d034
Update source/docs/software/advanced-controls/introduction/approaches…
gerth2 779f1c5
kebab case, not snake case.
gerth2 930c8e0
WIP wording cleanups, missing wording in sections, section heading style
gerth2 f790683
Missed some section headings
gerth2 8b872d6
wip arm sim
gerth2 b1e3280
arm wip - getting closer!
gerth2 b618526
Graphical tweaks and adding cosin feed forward term
gerth2 55aecc0
wip javascript refactor
gerth2 c9428df
wip automatically minifying a folder of js to a single included file
gerth2 bb60a12
renames and bugfixes
gerth2 a073289
visual apearance and link fixups
gerth2 b01dafa
more wording
gerth2 80921fb
cleanup and methodlogy description
gerth2 c545541
Update source/docs/software/advanced-controls/introduction/introducti…
gerth2 a8541cb
Update source/docs/software/advanced-controls/introduction/tuning-pid…
gerth2 001f8c9
Update source/index.rst
gerth2 8c25a76
Update source/docs/software/advanced-controls/introduction/introducti…
gerth2 e51f0dd
Update source/docs/software/advanced-controls/introduction/tuning-pid…
gerth2 1595e42
Update source/docs/software/advanced-controls/introduction/tuning-pid…
gerth2 dd6107d
Update source/docs/software/advanced-controls/introduction/pid-video.rst
gerth2 87f54c1
Update source/docs/software/advanced-controls/introduction/tuning-pid…
gerth2 f219aea
Update source/docs/software/advanced-controls/introduction/tuning-pid…
gerth2 7ba21b5
Update source/docs/software/advanced-controls/introduction/tuning-pid…
gerth2 314ed08
resolving spelling errors and hyphenated feed-forward
gerth2 30336c8
resolved a bunch more conversations
gerth2 2b26f23
Update source/docs/software/advanced-controls/introduction/tuning-pid…
gerth2 45d37b8
resolved the remainder of Yotam's questions
gerth2 38aa374
wip covering some of oblarg's comments
gerth2 7cd7e2d
All the comments have been accounted for! Huzzah!
gerth2 2fefdf6
lint fixups pt 1
gerth2 710f35d
lint check fixups pt 2
gerth2 2cdca64
black window reformat
gerth2 0741a60
attempt to fix sphinx build
gerth2 ad385a1
missed js renames which broke things.
gerth2 00eb4b8
added ball to flywheel visualization
gerth2 4d9c28b
adjusted PID range
gerth2 d108b77
rewording and split voltage graph
gerth2 bd2ef40
cleaned up multi-chart formatting, added more plant/controller termin…
gerth2 82dbb5f
lint fixes
gerth2 b338740
Axis title fixups
gerth2 776cbc8
Reorganized tuning exercises to be by mechanism, not by control techi…
gerth2 d0b47d0
fixing redirect and a bit of wording
gerth2 cbcb8b8
Merge remote-tracking branch 'origin/main' into gerth2_pid_tuning_upd…
gerth2 abd4707
actually fixed redirects
gerth2 2f5bde0
redirects append
gerth2 8e54f01
Delete black_windows.exe
gerth2 8f6f7ff
github comment fixup
gerth2 f1878cd
moved inputs to use text input (not number) to inhibit undesired vali…
gerth2 5fc6f3e
Merge remote-tracking branch 'origin/main' into gerth2_pid_tuning_upd…
gerth2 fb44569
add turret tuning article, restructure some other stuff to match
Oblarg 0cfcc60
add section on when feedforward control is necessary
Oblarg e5a65ba
update structure (not simulations) of flywheel article
Oblarg 914e1b8
finish structural changes, propagate to vertical arm (minus some todos)
Oblarg c3964c8
update index, links, add intro to feedforward, general improvements
Oblarg 622815d
try to restrict simulation to feedforward/feedback/both
Oblarg 6934b0b
finish flywheel article revamp
Oblarg ec8b2e6
add click interaction to arm position demo
Oblarg e0c7c9b
fix x axis value
Oblarg 3db9004
Change vertical arm plant params to be reasonable
Oblarg 31c613f
finish vertical arm
Oblarg cd5ab4e
make vertical arm controller timing correct, record 10s
Oblarg 4be48f7
color consistency, plot labeling
Oblarg c305471
add control effort to vertical arm visualization
Oblarg ec2726b
fix various build woopsies
Oblarg e856c5a
tune sizes
Oblarg d07a840
Add vector representation to flywheel visualization
Oblarg c13be9c
add turret simulation
Oblarg cbc6ad3
improve recommended turret kd gain
Oblarg e6ac903
spelling and formatting
Oblarg bc4b293
[DRAFT] add turret tuning article, restructure some other stuff to ma…
Oblarg c8dc4ab
Apply suggestions from code review
Daltz333 fd8ac75
Merge remote-tracking branch 'origin/main' into gerth2_pid_tuning_upd…
gerth2 7075e5a
File name cleanup and better comments/cleanup in conf.py
gerth2 bb659a0
Merge remote-tracking branch 'gerth2/gerth2_pid_tuning_updates' into …
gerth2 cfdf77d
Merge remote-tracking branch 'origin/main' into gerth2_pid_tuning_upd…
gerth2 daaacaa
unbork. I am bad at merging.
gerth2 898e828
finally fixed conf.py failing CI
gerth2 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| .flex-grid { | ||
| display: flex; | ||
| margin: 5px; | ||
|
|
||
| } | ||
|
|
||
| @media (max-width: 600px) { | ||
| .flex-grid { | ||
| display: block; | ||
| margin: 5px; | ||
|
|
||
| } | ||
| } | ||
|
|
||
| .col { | ||
| flex: 1; | ||
| min-height: 300px; | ||
| margin: 5px; | ||
| } | ||
|
|
||
| controlTable { | ||
| margin: 5px; | ||
| } | ||
|
|
||
| .viz-div { | ||
| margin:10px; | ||
| border-style: solid; | ||
| border-width: 3px; | ||
| } | ||
|
|
||
|
|
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| class DelayLine | ||
| { | ||
| constructor(num_samples) | ||
| { | ||
| this.items = []; | ||
| this.desLen = num_samples; | ||
| } | ||
|
|
||
| addSample(val) | ||
| { | ||
| this.items.push(val) | ||
| this.num_samples++; | ||
| } | ||
|
|
||
| getSample() | ||
| { | ||
| if(this.items.length >= this.desLen){ | ||
| return this.items.shift() | ||
| } else { | ||
| return 0; | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| function drawArrow(context, fromx, fromy, tox, toy, arrowWidth, color){ | ||
| //variables to be used when creating the arrow | ||
| var headlen = 10; | ||
| var angle = Math.atan2(toy-fromy,tox-fromx); | ||
|
|
||
| context.save(); | ||
| context.strokeStyle = color; | ||
|
|
||
| //starting path of the arrow from the start square to the end square | ||
| //and drawing the stroke | ||
| context.beginPath(); | ||
| context.moveTo(fromx, fromy); | ||
| context.lineTo(tox, toy); | ||
| context.lineWidth = arrowWidth; | ||
| context.stroke(); | ||
|
|
||
| //starting a new path from the head of the arrow to one of the sides of | ||
| //the point | ||
| context.beginPath(); | ||
| context.moveTo(tox, toy); | ||
| context.lineTo(tox-headlen*Math.cos(angle-Math.PI/7), | ||
| toy-headlen*Math.sin(angle-Math.PI/7)); | ||
|
|
||
| //path from the side point of the arrow, to the other side point | ||
| context.lineTo(tox-headlen*Math.cos(angle+Math.PI/7), | ||
| toy-headlen*Math.sin(angle+Math.PI/7)); | ||
|
|
||
| //path from the side point back to the tip of the arrow, and then | ||
| //again to the opposite side point | ||
| context.lineTo(tox, toy); | ||
| context.lineTo(tox-headlen*Math.cos(angle-Math.PI/7), | ||
| toy-headlen*Math.sin(angle-Math.PI/7)); | ||
|
|
||
| //draws the paths created above | ||
| context.stroke(); | ||
| context.restore(); | ||
| } | ||
|
|
||
| const zip = (a, b) => a.map((k, i) => [k, b[i]]); | ||
|
|
||
| const gaussian = (mean, stdev) => { | ||
| let y2; | ||
| let use_last = false; | ||
| return function () { | ||
| let y1; | ||
| if (use_last) { | ||
| y1 = y2; | ||
| use_last = false; | ||
| } else { | ||
| let x1, x2, w; | ||
| do { | ||
| x1 = 2.0 * Math.random() - 1.0; | ||
| x2 = 2.0 * Math.random() - 1.0; | ||
| w = x1 * x1 + x2 * x2; | ||
| } while (w >= 1.0); | ||
| w = Math.sqrt((-2.0 * Math.log(w)) / w); | ||
| y1 = x1 * w; | ||
| y2 = x2 * w; | ||
| use_last = true; | ||
| } | ||
|
|
||
| return mean + stdev * y1; | ||
| } | ||
| } | ||
|
|
||
| const isNear = ([x1, y1], [x2, y2], tolerance) => { | ||
| const dx = x2 - x1; | ||
| const dy = y2 - y1; | ||
| return dx * dx + dy * dy <= tolerance * tolerance; | ||
| } | ||
|
|
||
| const scalarMultiplyState = (scalar, [posRad, velRadPerS]) => { | ||
| return [scalar * posRad, scalar * velRadPerS]; | ||
| } | ||
|
|
||
| const addState = (...states) => { | ||
| return states.reduce((prev, cur) => [prev[0] + cur[0], prev[1] + cur[1]] | ||
| ); | ||
| } | ||
|
|
||
| const secondOrderRK4 = (dstate, state, inputVolts, timestepS) => { | ||
| // These are sometimes named "k1" etc | ||
| const d1 = dstate(state, inputVolts); | ||
| const d2 = dstate(addState(state, scalarMultiplyState(0.5 * timestepS, d1)), inputVolts); | ||
| const d3 = dstate(addState(state, scalarMultiplyState(0.5 * timestepS, d2)), inputVolts); | ||
| const d4 = dstate(addState(state, scalarMultiplyState(timestepS, d3)), inputVolts); | ||
|
|
||
| return addState(state, | ||
| scalarMultiplyState(timestepS / 6, | ||
| addState(d1, | ||
| scalarMultiplyState(2, d2), | ||
| scalarMultiplyState(2, d3), | ||
| d4))); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,174 @@ | ||
| class BaseSim { | ||
| constructor(divIdPrefix, processVariableUnits, stateMin, stateMax) { | ||
| this.divIdPrefix = divIdPrefix; | ||
| this.speedGraph = null; | ||
| this.voltsGraph = null; | ||
| this.containerDiv = document.getElementById(divIdPrefix + "_container"); | ||
| let plotDrawDivVals = document.getElementById(divIdPrefix + "_plotVals"); | ||
| let plotDrawDivVolts = document.getElementById(divIdPrefix + "_plotVolts"); | ||
|
|
||
| this.processVariableChart = new Highcharts.Chart( | ||
| plotDrawDivVals, | ||
| defaultOptions | ||
| ); | ||
| this.voltsChart = new Highcharts.Chart(plotDrawDivVolts, defaultOptions); | ||
|
|
||
| this.voltsChart.addSeries({ name: "Control Effort", color: "green" }); | ||
| this.processVariableChart.addSeries({ | ||
| name: "Output", | ||
| color: "purple", | ||
| zIndex: 2, | ||
| }); | ||
| this.processVariableChart.addSeries({ | ||
| name: "Setpoint", | ||
| color: "red", | ||
| zIndex: 1, | ||
| }); | ||
|
|
||
| this.voltsChart.yAxis[0].setTitle({ text: "Volts" }); | ||
| this.processVariableChart.yAxis[0].setTitle({ text: processVariableUnits }); | ||
|
|
||
| this.voltsChart.yAxis[0].setOptions({ min: -14.0, max: 14.0 }); | ||
| this.processVariableChart.yAxis[0].setOptions({ | ||
| min: stateMin, | ||
| max: stateMax, | ||
| }); | ||
|
|
||
| this.visualizationDrawDiv = document.getElementById(divIdPrefix + "_viz"); | ||
|
|
||
| this.animationStartTimeS = null; | ||
| window.requestAnimationFrame((t) => this.animate(t)); | ||
|
|
||
| this.controlDrawDiv = document.getElementById(divIdPrefix + "_ctrls"); | ||
|
|
||
| this.animationReset = true; | ||
| } | ||
|
|
||
| resetData() { | ||
|
|
||
| } | ||
|
|
||
| animate(currentTimeMs) { | ||
| let currentTimeS = currentTimeMs / 1000.0; | ||
|
|
||
| if (this.animationReset) { | ||
| this.animationStartTimeS = currentTimeS; | ||
| this.animationReset = false; | ||
| } | ||
|
|
||
| let animationTimeS = (currentTimeS - this.animationStartTimeS) % this.simDurationS; | ||
|
|
||
| let timeIndex = Math.floor(animationTimeS / this.simulationTimestepS); | ||
|
|
||
| this.drawAnimation(timeIndex, animationTimeS); | ||
|
|
||
| window.requestAnimationFrame((t) => this.animate(t)); | ||
| } | ||
|
|
||
| setControlEffortData(data) { | ||
| this.voltsChart.series[0].setData(data, false, false, true); | ||
| } | ||
|
|
||
| setOutputData(data) { | ||
| this.processVariableChart.series[0].setData(data, false, false, true); | ||
| } | ||
|
|
||
| setSetpointData(data) { | ||
| this.processVariableChart.series[1].setData(data, false, false, true); | ||
| } | ||
|
|
||
| redraw() { | ||
| this.processVariableChart.xAxis[0].setExtremes( | ||
| 0.0, | ||
| this.simDurationS, | ||
| false | ||
| ); | ||
| this.voltsChart.xAxis[0].setExtremes(0.0, this.simDurationS, false); | ||
| this.processVariableChart.redraw(); | ||
| this.voltsChart.redraw(); | ||
| } | ||
|
|
||
| drawAnimation(timeIndex, animationTimeS) { | ||
| this.visualization.drawDynamic(timeIndex, animationTimeS); | ||
| } | ||
| } | ||
|
|
||
| let defaultOptions = { | ||
| credits: { | ||
| enabled: false, | ||
| }, | ||
|
|
||
| chart: { | ||
| zoomType: null, | ||
| animation: false, | ||
| ignoreHiddenSeries: true, | ||
| panning: false, | ||
| showAxes: true, | ||
| marginLeft: 80, // Keep all charts left aligned | ||
| spacingTop: 20, | ||
| spacingBottom: 20, | ||
| backgroundColor: { | ||
| linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, | ||
| stops: [ | ||
| [0, "rgb(255,255,255)"], | ||
| [1, "rgb(230,230,230)"], | ||
| ], | ||
| }, | ||
| }, | ||
|
|
||
| title: { | ||
| //disable title | ||
| text: null, | ||
| }, | ||
|
|
||
| xAxis: { | ||
| type: "linear", | ||
| title: "Time (sec)", | ||
| lineColor: "#000", | ||
| tickColor: "#000", | ||
| gridLineColor: "#BBB", | ||
| gridLineWidth: 1, | ||
| labels: { | ||
| style: { | ||
| color: "#222", | ||
| fontWeight: "bold", | ||
| }, | ||
| }, | ||
| title: { | ||
| style: { | ||
| color: "#222", | ||
| }, | ||
| }, | ||
| }, | ||
|
|
||
| legend: { | ||
| layout: "vertical", | ||
| align: "right", | ||
| verticalAlign: "top", | ||
| borderWidth: 1, | ||
| backgroundColor: "#ddd", | ||
| floating: true, | ||
| itemStyle: { | ||
| font: "9pt Trebuchet MS, Verdana, sans-serif", | ||
| color: "#222", | ||
| }, | ||
| }, | ||
|
|
||
| exporting: { | ||
| enabled: false, | ||
| }, | ||
|
|
||
| colors: ["#FF0000", "#0000FF", "#00BB00", "#FF00FF", "#00FFFF", "#FFFF00"], | ||
|
|
||
| plotOptions: { | ||
| line: { | ||
| marker: { | ||
| radius: 2, | ||
| }, | ||
| lineWidth: 3, | ||
| threshold: null, | ||
| animation: true, | ||
| }, | ||
| }, | ||
| series: [], | ||
| }; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.