-
Notifications
You must be signed in to change notification settings - Fork 9
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
Rewrite the heuristics for detach/reattach #207
Comments
The current 'is it okay to detach from the track' is implemented like so: //Check if the skater can detach from the track without immediately reattaching, given its velocity. See #172
okToDetach: function( skaterState, dt ) {
var ss = skaterState.leaveTrack();
var count = 0;
//Make sure the skater won't immediately re-collide with the track before allowing it to detach, see #172
for ( ; count <= 1; count++ ) {
ss = this.stepFreeFall( dt, ss, false );
if ( ss.track !== null && ss.track === skaterState.track ) {
return false;
}
}
return true;
} That is, it checks to see if it would immediately recollide with the track. However, this causes quirky behavior as noted in the screencast in #176. Instead we should always allow the skater to detach from the track if the acceleration exceeds v/r^2. |
Changing the above means we will also need to change the logic for when the skater reattaches--making sure it doesn't reattach within too few steps, time or distance from where the skater detached. |
I'm changing to more explicit heuristics like this: //Logic to see if it is okay to reattach to the track. See #207 #176 #194
okToAttach: function( skaterState, track, u ) {
var elapsedTime = this.time - this.lastDetachment.time;
var isTrackDifferent = track !== this.lastDetachment.track;
var dx = skaterState.positionX - this.lastDetachment.position.x;
var dy = skaterState.positionY - this.lastDetachment.position.y;
var euclideanDistance = Math.sqrt( dx * dx + dy * dy );
var deltaU = Math.abs( u - this.lastDetachment.u );
return isTrackDifferent || elapsedTime > 10.0 / 60.0 || euclideanDistance > 0.1 || deltaU > 0.1 || this.lastDetachment.arcLength > 0.2;
}, |
I'll commit my in-progress work shortly, but we will still need to address the case of storing and restoring the lastDetachment for purposes of returnSkater. |
This is kind of a mess--not sure whether to keep the detachment state stored in the EnergySkateParkModel, Skater or SkaterState (I think I have ruled out SkaterState for performance/complexity reasons). |
Committed above, but I still need to save/restore it for returnSkater (and load URL). |
I think this work is mainly completed, and it seems like it fixes many related problems. The problem is, the skater sometimes passes through the track where she didn't before (if it is a point very close to where the skater detached from the track). I tried to tune the parameters of the heuristic to minimize this as much as possible, but I can still see it occurring in some cases. We may have to decide whether falling through the track (after recently jumping off the track) sometimes is an acceptable tradeoff for solving the issues addressed by this fix. |
For instance, here is a track that the skater passes through. Launch, then press return skater:
|
I am uncertain of the underlying cause of the above problem that causes the skater to pass through the track near the inflection point. Would be excellent to visualize it or step through it, to try to identify the source of the problem. |
The skater is leaving the track with the velocity vector parallel to the track. This means sometimes it goes above and sometimes it goes below the track. I investigated "nudging" the velocity vector above the track using this algorithm: //Nudge the velocity in the 'up' direction so the skater won't pass through the track, see #207
var velocity = new Vector2( freeSkater.velocityX, freeSkater.velocityY );
var upVector = new Vector2( sideVectorX, sideVectorY );
var revisedVelocity = velocity.normalized().blend( upVector, 0.01 ).normalized().times( velocity.magnitude() );
freeSkater = freeSkater.updateUDVelocity( 0, revisedVelocity.x, revisedVelocity.y ); And it solved the 5 or so recorded error cases. Also, nudging the direction of the velocity is guaranteed to conserve energy (compared to nudging the position). I still saw a "pass through track" error in debugTrack=8 with reduced friction, so this needs further investigation and testing. |
This is looking much better in the latest version. Dev testing will reveal if there are issues related to this, but it doesn't need specific testing as part of this issue. Closing. |
See #176
The text was updated successfully, but these errors were encountered: