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

Rewrite the heuristics for detach/reattach #207

Closed
samreid opened this issue Aug 29, 2014 · 11 comments
Closed

Rewrite the heuristics for detach/reattach #207

samreid opened this issue Aug 29, 2014 · 11 comments
Assignees

Comments

@samreid
Copy link
Member

samreid commented Aug 29, 2014

See #176

@samreid
Copy link
Member Author

samreid commented Aug 29, 2014

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.

@samreid
Copy link
Member Author

samreid commented Aug 29, 2014

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.

@samreid
Copy link
Member Author

samreid commented Aug 29, 2014

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;
    },

@samreid
Copy link
Member Author

samreid commented Aug 29, 2014

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.

@samreid
Copy link
Member Author

samreid commented Aug 29, 2014

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).

@samreid
Copy link
Member Author

samreid commented Aug 29, 2014

Committed above, but I still need to save/restore it for returnSkater (and load URL).

@samreid
Copy link
Member Author

samreid commented Aug 29, 2014

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.

@samreid
Copy link
Member Author

samreid commented Aug 29, 2014

For instance, here is a track that the skater passes through. Launch, then press return skater:

http://localhost:8080/energy-skate-park-basics/energy-skate-park-basics_en.html?state=%7B%22screen0%22%3A%7B%22model%22%3A%7B%22properties%22%3A%7B%22pieChartVisible%22%3Afalse%2C%22barGraphVisible%22%3Afalse%2C%22gridVisible%22%3Afalse%2C%22speedometerVisible%22%3Afalse%2C%22editButtonEnabled%22%3Atrue%2C%22clearButtonEnabled%22%3Atrue%2C%22paused%22%3Afalse%2C%22speed%22%3A%22normal%22%2C%22friction%22%3A0%2C%22detachable%22%3Afalse%2C%22editing%22%3Afalse%2C%22availableModelBounds%22%3A%7B%22minX%22%3A-8.34%2C%22minY%22%3A0%2C%22maxX%22%3A8.34%2C%22maxY%22%3A14.705602941176469%7D%2C%22scene%22%3A0%7D%2C%22skater%22%3A%7B%22properties%22%3A%7B%22track%22%3A-1%2C%22u%22%3A0%2C%22uD%22%3A0%2C%22up%22%3Atrue%2C%22gravity%22%3A-9.8%2C%22position%22%3A%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A3.5%2C%22y%22%3A0%7D%2C%22mass%22%3A62.5%2C%22direction%22%3A%22left%22%2C%22velocity%22%3A%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A0%2C%22y%22%3A0%7D%2C%22dragging%22%3Afalse%2C%22kineticEnergy%22%3A0%2C%22potentialEnergy%22%3A0%2C%22thermalEnergy%22%3A0%2C%22totalEnergy%22%3A0%2C%22angle%22%3A0%2C%22startingPosition%22%3A%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A3.5%2C%22y%22%3A0%7D%2C%22startingU%22%3A0%2C%22startingUp%22%3Atrue%2C%22startingTrack%22%3A-1%2C%22headPosition%22%3A%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A0%2C%22y%22%3A0%7D%7D%7D%2C%22tracks%22%3A%5B%7B%22physical%22%3Atrue%2C%22points%22%3A%5B%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-4%2C%22y%22%3A6%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A0%2C%22y%22%3A0%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A4%2C%22y%22%3A6%7D%5D%7D%2C%7B%22physical%22%3Afalse%2C%22points%22%3A%5B%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-4%2C%22y%22%3A6%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-2%2C%22y%22%3A1.2%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A2%2C%22y%22%3A0%7D%5D%7D%2C%7B%22physical%22%3Afalse%2C%22points%22%3A%5B%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-4%2C%22y%22%3A5%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-2%2C%22y%22%3A0.0166015%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A0%2C%22y%22%3A2%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A2%2C%22y%22%3A1%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A4%2C%22y%22%3A5%7D%5D%7D%5D%7D%7D%2C%22screen1%22%3A%7B%22model%22%3A%7B%22properties%22%3A%7B%22pieChartVisible%22%3Afalse%2C%22barGraphVisible%22%3Afalse%2C%22gridVisible%22%3Afalse%2C%22speedometerVisible%22%3Afalse%2C%22editButtonEnabled%22%3Atrue%2C%22clearButtonEnabled%22%3Atrue%2C%22paused%22%3Afalse%2C%22speed%22%3A%22normal%22%2C%22friction%22%3A0.05%2C%22detachable%22%3Afalse%2C%22editing%22%3Afalse%2C%22availableModelBounds%22%3A%7B%22minX%22%3A-8.34%2C%22minY%22%3A0%2C%22maxX%22%3A8.34%2C%22maxY%22%3A14.705602941176469%7D%2C%22scene%22%3A0%7D%2C%22skater%22%3A%7B%22properties%22%3A%7B%22track%22%3A-1%2C%22u%22%3A0%2C%22uD%22%3A0%2C%22up%22%3Atrue%2C%22gravity%22%3A-9.8%2C%22position%22%3A%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A3.5%2C%22y%22%3A0%7D%2C%22mass%22%3A62.5%2C%22direction%22%3A%22left%22%2C%22velocity%22%3A%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A0%2C%22y%22%3A0%7D%2C%22dragging%22%3Afalse%2C%22kineticEnergy%22%3A0%2C%22potentialEnergy%22%3A0%2C%22thermalEnergy%22%3A0%2C%22totalEnergy%22%3A0%2C%22angle%22%3A0%2C%22startingPosition%22%3A%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A3.5%2C%22y%22%3A0%7D%2C%22startingU%22%3A0%2C%22startingUp%22%3Atrue%2C%22startingTrack%22%3A-1%2C%22headPosition%22%3A%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A0%2C%22y%22%3A0%7D%7D%7D%2C%22tracks%22%3A%5B%7B%22physical%22%3Atrue%2C%22points%22%3A%5B%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-4%2C%22y%22%3A6%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A0%2C%22y%22%3A0%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A4%2C%22y%22%3A6%7D%5D%7D%2C%7B%22physical%22%3Afalse%2C%22points%22%3A%5B%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-4%2C%22y%22%3A6%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-2%2C%22y%22%3A1.2%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A2%2C%22y%22%3A0%7D%5D%7D%2C%7B%22physical%22%3Afalse%2C%22points%22%3A%5B%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-4%2C%22y%22%3A5%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-2%2C%22y%22%3A0.0166015%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A0%2C%22y%22%3A2%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A2%2C%22y%22%3A1%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A4%2C%22y%22%3A5%7D%5D%7D%5D%7D%7D%2C%22screen2%22%3A%7B%22model%22%3A%7B%22properties%22%3A%7B%22pieChartVisible%22%3Afalse%2C%22barGraphVisible%22%3Afalse%2C%22gridVisible%22%3Afalse%2C%22speedometerVisible%22%3Afalse%2C%22editButtonEnabled%22%3Atrue%2C%22clearButtonEnabled%22%3Atrue%2C%22paused%22%3Afalse%2C%22speed%22%3A%22normal%22%2C%22friction%22%3A0%2C%22detachable%22%3Atrue%2C%22editing%22%3Afalse%2C%22availableModelBounds%22%3A%7B%22minX%22%3A-8.34%2C%22minY%22%3A0%2C%22maxX%22%3A8.34%2C%22maxY%22%3A14.705602941176469%7D%7D%2C%22skater%22%3A%7B%22properties%22%3A%7B%22track%22%3A1%2C%22u%22%3A0.6020322109106928%2C%22uD%22%3A1.6243051260514414%2C%22up%22%3Afalse%2C%22gravity%22%3A-9.8%2C%22position%22%3A%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A0.5079727018404461%2C%22y%22%3A4.963996959636071%7D%2C%22mass%22%3A62.5%2C%22direction%22%3A%22left%22%2C%22velocity%22%3A%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-0.40315074996132844%2C%22y%22%3A-1.5734791435931395%7D%2C%22dragging%22%3Afalse%2C%22kineticEnergy%22%3A82.44897320365565%2C%22potentialEnergy%22%3A3040.4481377770935%2C%22thermalEnergy%22%3A1076.5199846122327%2C%22totalEnergy%22%3A4199.417095592982%2C%22angle%22%3A4.9632095156759455%2C%22startingPosition%22%3A%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A3.59110588235294%2C%22y%22%3A6.8561911764705865%7D%2C%22startingU%22%3Anull%2C%22startingUp%22%3Atrue%2C%22startingTrack%22%3A-1%2C%22headPosition%22%3A%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-1.4536632092163277%2C%22y%22%3A5.466599737635207%7D%7D%7D%2C%22tracks%22%3A%5B%7B%22physical%22%3Afalse%2C%22points%22%3A%5B%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-6.1%2C%22y%22%3A-0.85%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-5.1%2C%22y%22%3A-0.85%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-4.1%2C%22y%22%3A-0.85%7D%5D%7D%2C%7B%22physical%22%3Atrue%2C%22points%22%3A%5B%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A5.121741176470588%2C%22y%22%3A6.483344117647057%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A0.05887058823529401%2C%22y%22%3A1.0476264705882334%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-1.9427294117647067%2C%22y%22%3A2.637132352941175%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-3.1201411764705886%2C%22y%22%3A6.404849999999999%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A0.5690823529411766%2C%22y%22%3A6.071249999999999%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-2.3940705882352944%2C%22y%22%3A1.3419794117647044%7D%2C%7B%22_type%22%3A%22Vector2%22%2C%22x%22%3A-5.474964705882353%2C%22y%22%3A6.5029676470588225%7D%5D%7D%5D%7D%7D%2C%22simModel%22%3A%7B%22showHomeScreen%22%3Afalse%2C%22screenIndex%22%3A2%7D%7D

@samreid
Copy link
Member Author

samreid commented Aug 29, 2014

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.

@samreid
Copy link
Member Author

samreid commented Sep 3, 2014

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.

samreid added a commit that referenced this issue Sep 3, 2014
samreid added a commit that referenced this issue Sep 4, 2014
@samreid
Copy link
Member Author

samreid commented Sep 4, 2014

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.

@samreid samreid closed this as completed Sep 4, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant