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

Max Acceleration doesn't seem to limit changes in direction #120

Open
polarbub opened this issue Feb 3, 2025 · 1 comment
Open

Max Acceleration doesn't seem to limit changes in direction #120

polarbub opened this issue Feb 3, 2025 · 1 comment

Comments

@polarbub
Copy link

polarbub commented Feb 3, 2025

The max acceleration constraint doesn't seem to affect the cornering speed of my robot. When my robot does a u-turn, but keeps a constant heading roadrunner tries to send the robot through the corner at the max speed. This is much too much acceleration for the robot, so it not able to make the turn. It seems to me that roadrunner should decrease speed for the corner as direction and therefor velocity is changing and that change in velocity exceeds the max acceleration.

To solve this issue on the robot I used a TranslationalVelConstraint, but this is sub-optimal as it has to be added to each path segment that needs to have a limit applied. It also doesn't maximize the performance of the robot.

I have set up meepmeep with a path similar to the one causing issues. In the first video the max acceleration is set to 30 in/sec^2 and in the second one it is set to 60. It does take longer to get up to the max speed, but they both go through the corner at the same speed.

30.accel.mov
60.accel.mov

Here is the path code that was used to make the two videos:

import com.acmerobotics.roadrunner.*;
import com.noahbres.meepmeep.MeepMeep;
import com.noahbres.meepmeep.roadrunner.DefaultBotBuilder;
import com.noahbres.meepmeep.roadrunner.entity.RoadRunnerBotEntity;

import java.lang.Math;

public class MeepMeepTesting {
    public static void main(String[] args) {
        System.setProperty("sun.java2d.opengl", "true");

        MeepMeep meepMeep = new MeepMeep(800);
        RoadRunnerBotEntity bot = new DefaultBotBuilder(meepMeep)
                .setConstraints(30.0, 30.0, Math.toRadians(60.0), Math.toRadians(60.0), 15.0)
                .build();

        bot.runAction(
                bot.getDrive().actionBuilder(new Pose2d(-30, 0, 0))
                        .splineToConstantHeading(new Vector2d(10, 0), Math.toRadians(0))
                        .splineToConstantHeading(new Vector2d(15, 5), Math.toRadians(90))
                        .splineToConstantHeading(new Vector2d(10, 10), Math.toRadians(180))
                        .splineToConstantHeading(new Vector2d(-30, 10), Math.toRadians(180))
                        .build()
        );

        meepMeep.setBackground(MeepMeep.Background.FIELD_INTO_THE_DEEP_JUICE_DARK)
                .setDarkMode(true)
                .setBackgroundAlpha(0.95f)
                .addEntity(bot)
                .start();
    }
}
@rbrott
Copy link
Member

rbrott commented Feb 4, 2025

The max acceleration constraint doesn't seem to affect the cornering speed of my robot.

Correct, it only affects acceleration along the path and is blind to the curve the path traces through space.

When my robot does a u-turn, but keeps a constant heading roadrunner tries to send the robot through the corner at the max speed. This is much too much acceleration for the robot, so it not able to make the turn.

It seems to me that roadrunner should decrease speed for the corner as direction and therefor velocity is changing and that change in velocity exceeds the max acceleration.

One thing you can try is adding a constraint on the angular velocity that there would be if the vehicle was following the path tangent. Here's a quick demo: https://rr.brott.dev/playground/?30611f9869cfb28b.

eeaad7aa-06a1-4289-99cd-9ebf77f2e1b8.mp4

Code here in case the playground doesn't survive forever:

import com.acmerobotics.roadrunner.*
import kotlin.math.PI

@JvmOverloads
fun actionBuilder(beginPose: Pose2d, assumeTangentHeading: Boolean) =
    TrajectoryActionBuilder(
        ::TurnAction,
        ::TrajectoryAction,
        beginPose,
        eps = 1e-6,
        beginEndVel = 0.0,
        TurnConstraints(PI / 2, -PI / 2, PI / 2),
        MinVelConstraint(
            listOf(
                TranslationalVelConstraint(40.0),
                if (assumeTangentHeading) {
                    object : VelConstraint {
                        val base = AngularVelConstraint(PI / 2)
                        override fun maxRobotVel(robotPose: Pose2dDual<Arclength>, path: PosePath, s: Double) = path[s, 3].let {
                            base.maxRobotVel(Pose2dDual(it.position, it.position.drop(1).angleCast()), path, s)
                        }
                    }
                } else {
                    AngularVelConstraint(PI / 2)
                },
            )
        ),
        ProfileAccelConstraint(-30.0, 50.0),
        dispResolution = 0.25,
        angResolution = 0.1,
    )

fun main() {
    val original = actionBuilder(Pose2d(-30.0, 0.0, 0.0), assumeTangentHeading = true)
        .splineToConstantHeading(Vector2d(10.0, 0.0), 0.0)
        .splineToConstantHeading(Vector2d(15.0, 5.0), PI / 2)
        .splineToConstantHeading(Vector2d(10.0, 10.0), PI)
        .splineToConstantHeading(Vector2d(-30.0, 10.0), PI)
        .build()
        
    val tangent = actionBuilder(Pose2d(-30.0, 0.0, 0.0), assumeTangentHeading = false)
        .splineTo(Vector2d(10.0, 0.0), 0.0)
        .splineTo(Vector2d(15.0, 5.0), PI / 2)
        .splineTo(Vector2d(10.0, 10.0), PI)
        .splineTo(Vector2d(-30.0, 10.0), PI)
        .build()
        
    showActionVideo(original, fps=30)
    // showActionVideo(tangent, fps=30)
}

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

2 participants