acmerobotics/road-runner-quickstart

RR 1.11 angular ramp logger giving error

Zw96042 opened this issue · 10 comments

After running the angular ramp logger and stopping it, we go to check the results, and once we input the details and press the latest button, it gives this error.

TypeError: Reduce of empty array with no initial value
TypeError: Reduce of empty array with no initial value
at Array.reduce ()
at d (http://192.168.43.1:8080/assets/common-dae3fb6c.js:3611:124780)
at http://192.168.43.1:8080/assets/common-dae3fb6c.js:3611:125844
at B (http://192.168.43.1:8080/assets/common-dae3fb6c.js:3611:127379)
at id (http://192.168.43.1:8080/assets/common-dae3fb6c.js:3611:127613)
at async HTMLButtonElement. (http://192.168.43.1:8080/assets/common-dae3fb6c.js:3611:130923)

We have used the dead wheel direction debugger and those seem to be working. We have tuned RR before and are trying to retune it after they have changed various components. When retuning we set all values back to 0 to start from the top. Here are some of our angular ramp log files.

2024_01_07__15_40_36_350__AngularRampLogger.log
2024_01_07__16_03_41_683__ForwardRampLogger.log
2024_01_07__16_25_43_738__AngularRampLogger.log

Side note: I also increased the maxWheelVel to 70 and the maxProfileAccel to 60. Our robot is fairly light so I think it should be fine but might be worth mentioning.

Are you on the right tuning page (i.e., the one for dead wheels and not the one for drive encoders)? Thanks for the logs, but the tuning JSON file would actually be more helpful here.

Yes, I am on the correct link (http://192.168.43.1:8080/tuning/dead-wheel-angular-ramp.html). Attached is a tuning JSON file.

angular-ramp-1779797129596.json

To me, it looks empty (as in not very filled out) but I might not be viewing it correctly.

Oh funny. Is your code available somewhere? I'm mostly interested in TuningOpModes.java if you just want to attach that.

Sure. Let me know anything else I can provide.

`package org.firstinspires.ftc.teamcode.opmode.tuning;

import com.acmerobotics.dashboard.FtcDashboard;
import com.acmerobotics.dashboard.config.reflection.ReflectionConfig;
import com.acmerobotics.roadrunner.MotorFeedforward;
import com.acmerobotics.roadrunner.Pose2d;
import com.acmerobotics.roadrunner.ftc.AngularRampLogger;
import com.acmerobotics.roadrunner.ftc.DeadWheelDirectionDebugger;
import com.acmerobotics.roadrunner.ftc.DriveType;
import com.acmerobotics.roadrunner.ftc.DriveView;
import com.acmerobotics.roadrunner.ftc.DriveViewFactory;
import com.acmerobotics.roadrunner.ftc.Encoder;
import com.acmerobotics.roadrunner.ftc.ForwardPushTest;
import com.acmerobotics.roadrunner.ftc.ForwardRampLogger;
import com.acmerobotics.roadrunner.ftc.LateralPushTest;
import com.acmerobotics.roadrunner.ftc.LateralRampLogger;
import com.acmerobotics.roadrunner.ftc.ManualFeedforwardTuner;
import com.acmerobotics.roadrunner.ftc.MecanumMotorDirectionDebugger;
import com.qualcomm.hardware.lynx.LynxModule;
import com.qualcomm.robotcore.eventloop.opmode.OpMode;
import com.qualcomm.robotcore.eventloop.opmode.OpModeManager;
import com.qualcomm.robotcore.eventloop.opmode.OpModeRegistrar;

import org.firstinspires.ftc.robotcore.internal.opmode.OpModeMeta;
import org.firstinspires.ftc.teamcode.common.drive.drivetrain.MecanumDriveRR;
import org.firstinspires.ftc.teamcode.common.drive.localizer.ThreeDeadWheelLocalizer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public final class TuningOpModes {
// TODO: change this to TankDrive.class if you're using tank
public static final Class<?> DRIVE_CLASS = MecanumDriveRR.class;

public static final String GROUP = "quickstart";
public static final boolean DISABLED = false;

private TuningOpModes() {}

private static OpModeMeta metaForClass(Class<? extends OpMode> cls) {
    return new OpModeMeta.Builder()
            .setName(cls.getSimpleName())
            .setGroup(GROUP)
            .setFlavor(OpModeMeta.Flavor.TELEOP)
            .build();
}

@OpModeRegistrar
public static void register(OpModeManager manager) {
    if (DISABLED) return;

    DriveViewFactory dvf;
    dvf = hardwareMap -> {
        MecanumDriveRR md = new MecanumDriveRR(hardwareMap, new Pose2d(0, 0, 0));

        List<Encoder> leftEncs = new ArrayList<>(), rightEncs = new ArrayList<>();
        List<Encoder> parEncs = new ArrayList<>(), perpEncs = new ArrayList<>();
        if (md.localizer instanceof MecanumDriveRR.DriveLocalizer) {
            MecanumDriveRR.DriveLocalizer dl = (MecanumDriveRR.DriveLocalizer) md.localizer;
            leftEncs.add(dl.leftFront);
            leftEncs.add(dl.leftBack);
            rightEncs.add(dl.rightFront);
            rightEncs.add(dl.rightBack);
        } else if (md.localizer instanceof ThreeDeadWheelLocalizer) {
            ThreeDeadWheelLocalizer dl = (ThreeDeadWheelLocalizer) md.localizer;
            parEncs.add(dl.par0);
            parEncs.add(dl.par1);
            perpEncs.add(dl.perp);
        } else {
            throw new RuntimeException("unknown localizer: " + md.localizer.getClass().getName());
        }

        return new DriveView(
                DriveType.MECANUM,
                MecanumDriveRR.PARAMS.inPerTick,
                MecanumDriveRR.PARAMS.maxWheelVel,
                MecanumDriveRR.PARAMS.minProfileAccel,
                MecanumDriveRR.PARAMS.maxProfileAccel,
                hardwareMap.getAll(LynxModule.class),
                Arrays.asList(
                        md.leftFront,
                        md.leftBack
                ),
                Arrays.asList(
                        md.rightFront,
                        md.rightBack
                ),
                leftEncs,
                rightEncs,
                parEncs,
                perpEncs,
                md.imu,
                md.voltageSensor,
                () -> new MotorFeedforward(MecanumDriveRR.PARAMS.kS,
                    MecanumDriveRR.PARAMS.kV / MecanumDriveRR.PARAMS.inPerTick,
                    MecanumDriveRR.PARAMS.kA / MecanumDriveRR.PARAMS.inPerTick)
        );
    };

    manager.register(metaForClass(AngularRampLogger.class), new AngularRampLogger(dvf));
    manager.register(metaForClass(ForwardPushTest.class), new ForwardPushTest(dvf));
    manager.register(metaForClass(ForwardRampLogger.class), new ForwardRampLogger(dvf));
    manager.register(metaForClass(LateralPushTest.class), new LateralPushTest(dvf));
    manager.register(metaForClass(LateralRampLogger.class), new LateralRampLogger(dvf));
    manager.register(metaForClass(ManualFeedforwardTuner.class), new ManualFeedforwardTuner(dvf));
    manager.register(metaForClass(MecanumMotorDirectionDebugger.class), new MecanumMotorDirectionDebugger(dvf));
    manager.register(metaForClass(DeadWheelDirectionDebugger.class), new DeadWheelDirectionDebugger(dvf));

    manager.register(metaForClass(ManualFeedbackTuner.class), ManualFeedbackTuner.class);
    manager.register(metaForClass(SplineTest.class), SplineTest.class);
    manager.register(metaForClass(LocalizationTest.class), LocalizationTest.class);

    FtcDashboard.getInstance().withConfigRoot(configRoot -> {
        for (Class<?> c : Arrays.asList(
                AngularRampLogger.class,
                ForwardRampLogger.class,
                LateralRampLogger.class,
                ManualFeedforwardTuner.class,
                MecanumMotorDirectionDebugger.class,
                ManualFeedbackTuner.class
        )) {
            configRoot.putVariable(c.getSimpleName(), ReflectionConfig.createVariableFromClass(c));
        }
    });
}

}`

Okay that seems basically unmodified. And you're pretty sure the robot actually moved? It really looks like the opmode was inited and then stopped. Is this repeatable? Maybe try running again.

Yes, I am sure that the robot turned in place. I have run it about 5 times and for around 15-20 seconds each. Would you like me to publish my whole code somewhere?

Does the timestamp on the downloaded file actually change between repeats?

I am fairly certain it does. Although I do not currently have the robot to test that.

I suspect something weird was going on with the system time because 1779797129596 ms after the Unix epoch is in 2026, and so the file will seem to have been written after a new file written around now. Your best bet may be to nuke the /sdcard/FIRST/RoadRunner folder and then run again one last time (I think that's the right path).

When retrieving the logs some odd timestamps were confusing to me. Not sure what happened there. Thank you for your guidance.