# 20211220~20211226 程式組 ###### tags: `工作筆記 程式組` ## 20211221 ### 劉柏蔚 ```java= package frc.robot; import com.ctre.phoenix.motorcontrol.can.WPI_TalonFX; import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX; import edu.wpi.first.wpilibj.DigitalInput; import edu.wpi.first.wpilibj.Encoder; import edu.wpi.first.wpilibj.Joystick; import edu.wpi.first.wpilibj.SpeedController; import edu.wpi.first.wpilibj.SpeedControllerGroup; import edu.wpi.first.wpilibj.TimedRobot; import edu.wpi.first.wpilibj.drive.DifferentialDrive; import edu.wpi.first.wpilibj.smartdashboard.SendableChooser; import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; public class Robot extends TimedRobot { WPI_TalonSRX mLeftFront = new WPI_TalonSRX(1); WPI_TalonSRX mLeftBack = new WPI_TalonSRX(4); WPI_TalonSRX mRightFront = new WPI_TalonSRX(2); WPI_TalonSRX mRightBack = new WPI_TalonSRX(3); SpeedControllerGroup leftDrive = new SpeedControllerGroup(mLeftFront, mLeftBack); SpeedControllerGroup rightDrive = new SpeedControllerGroup(mRightFront, mRightBack); DifferentialDrive Drive = new DifferentialDrive(leftDrive, rightDrive); DigitalInput toplimitSwitch = new DigitalInput(0); DigitalInput bottomlimitSwitch = new DigitalInput(1); Encoder encoder = new Encoder(0, 1); Joystick js1 = new Joystick(0); @Override public void robotInit() { mLeftFront.setInverted(true); mLeftBack.setInverted(false); mRightFront.setInverted(false); mRightBack.setInverted(false); } @Override public void robotPeriodic() { } @Override public void autonomousInit() { } @Override public void autonomousPeriodic() { } @Override public void teleopInit() { } @Override public void teleopPeriodic() { setMotorSpeed(js1.getRawAxis(2)); if (js1.getRawButton(1)) Drive.arcadeDrive(js1.getRawAxis(1), js1.getRawAxis(1)); if (encoder.getDistance() < 5) { Drive.arcadeDrive(.5, .5); } else { Drive.arcadeDrive(0, 0); } } public void setMotorSpeed(double speed) { if (speed > 0) { if (toplimitSwitch.get()) { leftDrive.set(0); } else { leftDrive.set(speed); } } else { if (bottomlimitSwitch.get()) { leftDrive.set(0); } else { leftDrive.set(speed); } } if (speed > 0) { if (toplimitSwitch.get()) { rightDrive.set(0); } else { rightDrive.set(speed); } } else { if (bottomlimitSwitch.get()) { rightDrive.set(0); } else { rightDrive.set(speed); } } } @Override public void disabledInit() { } @Override public void disabledPeriodic() { } @Override public void testInit() { } @Override public void testPeriodic() { } } ``` ### 吳玠廷 ![](https://i.imgur.com/x1m4DaE.png) 按左邊的Eyedcopper再點選limelight偵測到的反光條就可以顯示出他離感應器中心的X,Y座標 ![](https://i.imgur.com/xdQNoUf.png)(官方的設定) ### 林俊彥 ``` package frc.robot; import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX; import com.kauailabs.navx.frc.AHRS; import edu.wpi.first.wpilibj.ADXRS450_Gyro; import edu.wpi.first.wpilibj.Joystick; import edu.wpi.first.wpilibj.SPI; import edu.wpi.first.wpilibj.SpeedController; import edu.wpi.first.wpilibj.SpeedControllerGroup; import edu.wpi.first.wpilibj.TimedRobot; import edu.wpi.first.wpilibj.drive.DifferentialDrive; import edu.wpi.first.wpilibj.drive.MecanumDrive; import edu.wpi.first.wpilibj.interfaces.Gyro; import edu.wpi.first.wpilibj.shuffleboard.Shuffleboard; import edu.wpi.first.wpilibj.smartdashboard.SendableChooser; import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; public class Robot extends TimedRobot { private static final String kDefaultAuto = "Default"; private static final String kCustomAuto = "My Auto"; private String m_autoSelected; private final SendableChooser<String> m_chooser = new SendableChooser<>(); public final int kFrontLeftChannel = 3; public final int kRearLeftChannel = 4; public final int kFrontRightChannel = 1; public final int kRearRightChannel = 2; public final int leftStick_X = 0; public final int leftStick_Y = 1; public final int rightStick_X = 4; public final int rightStick_Y = 5; public final int trigger_L = 2; public final int trigger_R = 3; public final int Btn_A = 1; public final int Btn_B = 2; public final int Btn_X = 3; public final int Btn_Y = 4; public final int Btn_LB = 5; public final int Btn_RB = 6; public final int Btn_LS = 9; public final int Btn_RS = 10; double ySpeed; double xSpeed; double zRotation; double kP = 1; double currentangle; Gyro gyro = new AHRS(SPI.Port.kMXP); WPI_TalonSRX m_frontLeft = new WPI_TalonSRX(kFrontLeftChannel); WPI_TalonSRX m_rearLeft = new WPI_TalonSRX(kRearLeftChannel); WPI_TalonSRX m_frontRight = new WPI_TalonSRX(kFrontRightChannel); WPI_TalonSRX m_rearRight = new WPI_TalonSRX(kRearRightChannel); SpeedControllerGroup left = new SpeedControllerGroup(m_frontLeft, m_rearLeft); SpeedControllerGroup right = new SpeedControllerGroup(m_frontRight, m_rearRight); DifferentialDrive drive = new DifferentialDrive(left, right); Joystick joystick = new Joystick(0); @Override public void robotInit() { m_frontRight.setInverted(true); m_rearRight.setInverted(true); m_frontLeft.setInverted(false); m_rearLeft.setInverted(false); SmartDashboard.putNumber("Gyro", gyro.getAngle()); currentangle = gyro.getAngle(); if(currentangle >= 360 ){ currentangle -= -360; } while(currentangle >= 5 || currentangle <= -5){ if(currentangle >=3)/*its turning left(rightspeed > leftspeed)*/{ left.set(0.8); right.set(0.1); }else{ right.set(0.8); left.set(0.1); } } } @Override public void robotPeriodic() { } @Override public void autonomousInit() { m_autoSelected = m_chooser.getSelected(); // m_autoSelected = SmartDashboard.getString("Auto Selector", kDefaultAuto); System.out.println("Auto selected: " + m_autoSelected); } @Override public void autonomousPeriodic() { double error = -gyro.getRate(); drive.tankDrive(.5 + kP * error, .5 - kP * error); } @Override public void teleopInit() { } @Override public void teleopPeriodic() { ySpeed = -joystick.getRawAxis(leftStick_Y) * -0.5; xSpeed = joystick.getRawAxis(leftStick_X)* -0.5; zRotation = joystick.getRawAxis(rightStick_X)* 0.5; m_frontLeft.set(ySpeed + xSpeed + zRotation); m_frontRight.set(ySpeed - xSpeed - zRotation); m_rearLeft.set(ySpeed - xSpeed + zRotation); m_rearRight.set(ySpeed + xSpeed - zRotation); } @Override public void disabledInit() { } @Override public void disabledPeriodic() { } @Override public void testInit() { } @Override public void testPeriodic() { } } ``` 目前有一部分錯誤 周四會進行小調整 ### 黃冠穎 今天大致看完PathWeaver的資料,程式也大致寫出來了,只是差一個RamseteConrtroller沒用好,但禮拜四要聖誕晚餐應該不會動到太多。程式晚點貼上來。更 程式在下面 ## 20211223 ### 魏仁祥 :::spoiler today's code ```java= package frc.robot; import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX; import com.kauailabs.navx.frc.AHRS; import edu.wpi.cscore.CvSink; import edu.wpi.cscore.CvSource; import edu.wpi.cscore.UsbCamera; import edu.wpi.first.cameraserver.CameraServer; import edu.wpi.first.networktables.NetworkTableEntry; import edu.wpi.first.networktables.NetworkTableInstance; import edu.wpi.first.wpilibj.AnalogInput; import edu.wpi.first.wpilibj.Joystick; import edu.wpi.first.wpilibj.SPI; import edu.wpi.first.wpilibj.SpeedControllerGroup; import edu.wpi.first.wpilibj.TimedRobot; import edu.wpi.first.wpilibj.drive.DifferentialDrive; import edu.wpi.first.wpilibj.drive.MecanumDrive; import edu.wpi.first.wpilibj.smartdashboard.SendableChooser; import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; import edu.wpi.first.networktables.NetworkTable; public class Robot extends TimedRobot { // PWM channels public final int kFrontLeftChannel = 3; public final int kRearLeftChannel = 1; public final int kFrontRightChannel = 4; public final int kRearRightChannel = 2; public final int joystickPort = 0; public final int rightUltrasonicPort = 1; public final int rearUltrasonicPort = 0; // driver station ports public final int leftStick_X = 0; public final int leftStick_Y = 1; public final int rightStick_X = 4; public final int rightStick_Y = 5; public final int trigger_L = 2; public final int trigger_R = 3; public final int Btn_A = 1; public final int Btn_B = 2; public final int Btn_X = 3; public final int Btn_Y = 4; public final int Btn_LB = 5; public final int Btn_RB = 6; public final int Btn_LS = 9; public final int Btn_RS = 10; // Motors WPI_TalonSRX m_frontLeft = new WPI_TalonSRX(kFrontLeftChannel); WPI_TalonSRX m_rearLeft = new WPI_TalonSRX(kRearLeftChannel); WPI_TalonSRX m_frontRight = new WPI_TalonSRX(kFrontRightChannel); WPI_TalonSRX m_rearRight = new WPI_TalonSRX(kRearRightChannel); // SpeedControllerGroup and DifferentialDrive SpeedControllerGroup leftGroup = new SpeedControllerGroup(m_frontLeft, m_rearLeft); SpeedControllerGroup rightGroup = new SpeedControllerGroup(m_frontRight, m_rearRight); DifferentialDrive drive = new DifferentialDrive(leftGroup, rightGroup); public MecanumDrive m_Drive; // Joystick Joystick joystick = new Joystick(joystickPort); // Gyro AHRS gyro = new AHRS(SPI.Port.kMXP); // Ultrasonic AnalogInput rightUltrasonic = new AnalogInput(rightUltrasonicPort); AnalogInput rearUltrasonic = new AnalogInput(rearUltrasonicPort); // Microsoft Camera UsbCamera camera = CameraServer.getInstance().startAutomaticCapture(); CvSink cvSink = CameraServer.getInstance().getVideo(); CvSource outputStream = CameraServer.getInstance().putVideo("Blur", 640, 480); // Limelight NetworkTable table = NetworkTableInstance.getDefault().getTable("limelight"); NetworkTableEntry tx = table.getEntry("tx"); // Horizontal Offset From Crosshair To Target (-27 degrees to 27 degrees) NetworkTableEntry ty = table.getEntry("ty"); // Vertical Offset From Crosshair To Target (-20.5 degrees to 20.5 degrees) NetworkTableEntry ta = table.getEntry("ta"); // Target Area (0% of image to 100% of image) NetworkTableEntry tv = table.getEntry("tv"); // Whether the limelight has any valid targets (0 or 1) // Variables (limelight) double x; double y; double area; boolean v; // Variables (drivetrain) double xSpeed; double ySpeed; double zRotation; // Variables (gyro) double currentAngle; @Override public void robotInit() { // drivetrain m_Drive = new MecanumDrive(m_frontLeft, m_rearLeft, m_frontRight, m_rearRight); // motors inverted m_frontRight.setInverted(true); m_rearRight.setInverted(true); m_frontLeft.setInverted(true); m_rearLeft.setInverted(true); } @Override public void robotPeriodic() { // read values periodically x = tx.getDouble(0.0); y = ty.getDouble(0.0); area = ta.getDouble(0.0); v = tv.getBoolean(false); // post to smart dashboard periodically (limelight) SmartDashboard.putNumber("LimelightX", x); SmartDashboard.putNumber("LimelightY", y); SmartDashboard.putNumber("LimelightArea", area); SmartDashboard.putBoolean("LimelightV", v); // post to smart dashboard periodically (gyro) currentAngle = gyro.getAngle(); if (currentAngle >= 360) currentAngle -= 360; else if (currentAngle <= 0) currentAngle += 360; SmartDashboard.putNumber("currentAngle", currentAngle); } @Override public void autonomousInit() {} /** This function is called periodically during autonomous. */ @Override public void autonomousPeriodic() {} /** This function is called once when teleop is enabled. */ @Override public void teleopInit() { //gyro.reset(); } void aimWithLimelight() { double KpSheering = 0.05; double heading_error = -x; double min_command = 0.3; double sheering_adjust = 0.0; if(x > 0.5) { sheering_adjust = KpSheering * heading_error - min_command; } else if (x < -0.5){ sheering_adjust = KpSheering * heading_error + min_command; } m_Drive.driveCartesian(0, 0, sheering_adjust * 0.5); SmartDashboard.putNumber("heading_error", heading_error); SmartDashboard.putNumber("sheering_adjust", sheering_adjust); } /** This function is called periodically during operator control. */ @Override public void teleopPeriodic() { // Gyro Reset if( joystick.getRawButton(Btn_Y) ){ gyro.reset(); } // drivetrain ySpeed = joystick.getRawAxis(leftStick_Y) * 0.5; xSpeed = -joystick.getRawAxis(leftStick_X) * 0.5; zRotation = -joystick.getRawAxis(rightStick_X) * 0.5; m_Drive.driveCartesian(ySpeed, xSpeed, zRotation); if(joystick.getRawButton(Btn_A)) { aimWithLimelight(); } } /** This function is called once when the robot is disabled. */ @Override public void disabledInit() {} /** This function is called periodically when disabled. */ @Override public void disabledPeriodic() {} /** This function is called once when test mode is enabled. */ @Override public void testInit() {} /** This function is called periodically during test mode. */ @Override public void testPeriodic() {} } ``` ::: 今天的我在和 matt 測試 limelight,做了這麼多我發現到還是在 limelight finder 找到目標物和確認 tx ty 都跑得動且是穩定的是最難的。完成上述後,我直接複製上次準備好的程式測試 tx 讓底盤瞄準反光布條且轉向目標物,因為底盤是 mecanum drivetrain 所以在思考自轉花了點時間,但後來還是完成了也有請許志恩和王智凱來協助測試。接著是 ty ,我們在調整 kp 時花了很多時間,但怎麼調都是條不好。後來經過測試後發現到如果一直按下 btn b 調整與目標物距離時,則有比較好,但這樣的話 auto 就可能沒辦法到很好,這個下禮拜二還要再測試才行。 ### 黃冠穎 今天把Pathweaver寫出來,我有自己寫的一段程式與找到的一段程式,這裡貼上的是Example Code,希望可以把兩個程式合在一起,能在下禮拜測試並修改程式。只是我不知道小台機器人有沒有Gyro跟Encoder,如果有下禮拜就應該可以測試,沒有的話應該測試不了。再說。上面是DriveSubsystem,下面是RobotContainer ```=java package frc.robot.subsystems; import edu.wpi.first.wpilibj.ADXRS450_Gyro; import edu.wpi.first.wpilibj.Encoder; import edu.wpi.first.wpilibj.PWMSparkMax; import edu.wpi.first.wpilibj.SpeedControllerGroup; import edu.wpi.first.wpilibj.drive.DifferentialDrive; import frc.robot.Constants.DriveConstants; import edu.wpi.first.wpilibj.geometry.Pose2d; import edu.wpi.first.wpilibj.interfaces.Gyro; import edu.wpi.first.wpilibj.kinematics.DifferentialDriveOdometry; import edu.wpi.first.wpilibj.kinematics.DifferentialDriveWheelSpeeds; import edu.wpi.first.wpilibj2.command.SubsystemBase; public class DriveSubsystem extends SubsystemBase { WPI_TalonFX leftFront = new WPI_TalonFX(DriveConstants.kLeftMotor1Port); WPI_TalonFX leftBack = new WPI_TalonFX(DriveConstants.kLeftMotor2Port); WPI_TalonFX rightFront = new WPI_TalonFX(DriveConstants.kRightMotor1Port); WPI_TalonFX rightBack = new WPI_TalonFX(DriveConstants.kRightMotor2Port); // The motors on the left side of the drive. private final SpeedControllerGroup m_leftMotors = new SpeedControllerGroup(leftFront,leftBack); // The motors on the right side of the drive. private final SpeedControllerGroup m_rightMotors = new SpeedControllerGroup(rightFront,rightBack); // The robot's drive private final DifferentialDrive m_drive = new DifferentialDrive(m_leftMotors, m_rightMotors); // The left-side drive encoder private final Encoder m_leftEncoder = new Encoder( DriveConstants.kLeftEncoderPorts[0], DriveConstants.kLeftEncoderPorts[1], DriveConstants.kLeftEncoderReversed); // The right-side drive encoder private final Encoder m_rightEncoder = new Encoder( DriveConstants.kRightEncoderPorts[0], DriveConstants.kRightEncoderPorts[1], DriveConstants.kRightEncoderReversed); // The gyro sensor private final Gyro m_gyro = new ADXRS450_Gyro(); // Odometry class for tracking robot pose private final DifferentialDriveOdometry m_odometry; /** Creates a new DriveSubsystem. */ public DriveSubsystem() { // Sets the distance per pulse for the encoders m_leftEncoder.setDistancePerPulse(DriveConstants.kEncoderDistancePerPulse); m_rightEncoder.setDistancePerPulse(DriveConstants.kEncoderDistancePerPulse); resetEncoders(); m_odometry = new DifferentialDriveOdometry(m_gyro.getRotation2d()); } @Override public void periodic() { // Update the odometry in the periodic block m_odometry.update( m_gyro.getRotation2d(), m_leftEncoder.getDistance(), m_rightEncoder.getDistance()); } /** * Returns the currently-estimated pose of the robot. * * @return The pose. */ public Pose2d getPose() { return m_odometry.getPoseMeters(); } /** * Returns the current wheel speeds of the robot. * * @return The current wheel speeds. */ public DifferentialDriveWheelSpeeds getWheelSpeeds() { return new DifferentialDriveWheelSpeeds(m_leftEncoder.getRate(), m_rightEncoder.getRate()); } /** * Resets the odometry to the specified pose. * * @param pose The pose to which to set the odometry. */ public void resetOdometry(Pose2d pose) { resetEncoders(); m_odometry.resetPosition(pose, m_gyro.getRotation2d()); } /** * Drives the robot using arcade controls. * * @param fwd the commanded forward movement * @param rot the commanded rotation */ public void arcadeDrive(double fwd, double rot) { m_drive.arcadeDrive(fwd, rot); } /** * Controls the left and right sides of the drive directly with voltages. * * @param leftVolts the commanded left output * @param rightVolts the commanded right output */ public void tankDriveVolts(double leftVolts, double rightVolts) { m_leftMotors.setVoltage(leftVolts); m_rightMotors.setVoltage(-rightVolts); m_drive.feed(); } /** Resets the drive encoders to currently read a position of 0. */ public void resetEncoders() { m_leftEncoder.reset(); m_rightEncoder.reset(); } /** * Gets the average distance of the two encoders. * * @return the average of the two encoder readings */ public double getAverageEncoderDistance() { return (m_leftEncoder.getDistance() + m_rightEncoder.getDistance()) / 2.0; } /** * Gets the left drive encoder. * * @return the left drive encoder */ public Encoder getLeftEncoder() { return m_leftEncoder; } /** * Gets the right drive encoder. * * @return the right drive encoder */ public Encoder getRightEncoder() { return m_rightEncoder; } /** * Sets the max output of the drive. Useful for scaling the drive to drive more slowly. * * @param maxOutput the maximum output to which the drive will be constrained */ public void setMaxOutput(double maxOutput) { m_drive.setMaxOutput(maxOutput); } /** Zeroes the heading of the robot. */ public void zeroHeading() { m_gyro.reset(); } /** * Returns the heading of the robot. * * @return the robot's heading in degrees, from -180 to 180 */ public double getHeading() { return m_gyro.getRotation2d().getDegrees(); } /** * Returns the turn rate of the robot. * * @return The turn rate of the robot, in degrees per second */ public double getTurnRate() { return -m_gyro.getRate(); } } ``` ```=java // Copyright (c) FIRST and other WPILib contributors. // Open Source Software; you can modify and/or share it under the terms of // the WPILib BSD license file in the root directory of this project. package frc.robot; import static edu.wpi.first.wpilibj.XboxController.Button; import edu.wpi.first.wpilibj.GenericHID; import edu.wpi.first.wpilibj.XboxController; import edu.wpi.first.wpilibj.controller.PIDController; import edu.wpi.first.wpilibj.controller.RamseteController; import edu.wpi.first.wpilibj.controller.SimpleMotorFeedforward; import frc.robot.Constants.AutoConstants; import frc.robot.Constants.DriveConstants; import frc.robot.Constants.OIConstants; import frc.robot.subsystems.DriveSubsystem; import edu.wpi.first.wpilibj.geometry.Pose2d; import edu.wpi.first.wpilibj.geometry.Rotation2d; import edu.wpi.first.wpilibj.geometry.Translation2d; import edu.wpi.first.wpilibj.trajectory.Trajectory; import edu.wpi.first.wpilibj.trajectory.TrajectoryConfig; import edu.wpi.first.wpilibj.trajectory.TrajectoryGenerator; import edu.wpi.first.wpilibj.trajectory.constraint.DifferentialDriveVoltageConstraint; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.RamseteCommand; import edu.wpi.first.wpilibj2.command.RunCommand; import edu.wpi.first.wpilibj2.command.button.JoystickButton; import java.util.List; /** * This class is where the bulk of the robot should be declared. Since Command-based is a * "declarative" paradigm, very little robot logic should actually be handled in the {@link Robot} * periodic methods (other than the scheduler calls). Instead, the structure of the robot (including * subsystems, commands, and button mappings) should be declared here. */ public class RobotContainer { // The robot's subsystems private final DriveSubsystem m_robotDrive = new DriveSubsystem(); // The driver's controller XboxController m_driverController = new XboxController(OIConstants.kDriverControllerPort); /** The container for the robot. Contains subsystems, OI devices, and commands. */ public RobotContainer() { // Configure the button bindings configureButtonBindings(); // Configure default commands // Set the default drive command to split-stick arcade drive m_robotDrive.setDefaultCommand( // A split-stick arcade command, with forward/backward controlled by the left // hand, and turning controlled by the right. new RunCommand( () -> m_robotDrive.arcadeDrive( m_driverController.getY(GenericHID.Hand.kLeft), m_driverController.getX(GenericHID.Hand.kRight)), m_robotDrive)); } /** * Use this method to define your button->command mappings. Buttons can be created by * instantiating a {@link GenericHID} or one of its subclasses ({@link * edu.wpi.first.wpilibj.Joystick} or {@link XboxController}), and then calling passing it to a * {@link JoystickButton}. */ private void configureButtonBindings() { // Drive at half speed when the right bumper is held new JoystickButton(m_driverController, Button.kBumperRight.value) .whenPressed(() -> m_robotDrive.setMaxOutput(0.5)) .whenReleased(() -> m_robotDrive.setMaxOutput(1)); } /** * Use this to pass the autonomous command to the main {@link Robot} class. * * @return the command to run in autonomous */ public Command getAutonomousCommand() { // Create a voltage constraint to ensure we don't accelerate too fast var autoVoltageConstraint = new DifferentialDriveVoltageConstraint( new SimpleMotorFeedforward( DriveConstants.ksVolts, DriveConstants.kvVoltSecondsPerMeter, DriveConstants.kaVoltSecondsSquaredPerMeter), DriveConstants.kDriveKinematics, 10); // Create config for trajectory TrajectoryConfig config = new TrajectoryConfig( AutoConstants.kMaxSpeedMetersPerSecond, AutoConstants.kMaxAccelerationMetersPerSecondSquared) // Add kinematics to ensure max speed is actually obeyed .setKinematics(DriveConstants.kDriveKinematics) // Apply the voltage constraint .addConstraint(autoVoltageConstraint); // An example trajectory to follow. All units in meters. Trajectory exampleTrajectory = TrajectoryGenerator.generateTrajectory( // Start at the origin facing the +X direction new Pose2d(0, 0, new Rotation2d(0)), // Pass through these two interior waypoints, making an 's' curve path List.of(new Translation2d(1, 1), new Translation2d(2, -1)), // End 3 meters straight ahead of where we started, facing forward new Pose2d(3, 0, new Rotation2d(0)), // Pass config config); RamseteCommand ramseteCommand = new RamseteCommand( exampleTrajectory, m_robotDrive::getPose, new RamseteController(AutoConstants.kRamseteB, AutoConstants.kRamseteZeta), new SimpleMotorFeedforward( DriveConstants.ksVolts, DriveConstants.kvVoltSecondsPerMeter, DriveConstants.kaVoltSecondsSquaredPerMeter), DriveConstants.kDriveKinematics, m_robotDrive::getWheelSpeeds, new PIDController(DriveConstants.kPDriveVel, 0, 0), new PIDController(DriveConstants.kPDriveVel, 0, 0), // RamseteCommand passes volts to the callback m_robotDrive::tankDriveVolts, m_robotDrive); // Reset odometry to the starting pose of the trajectory. m_robotDrive.resetOdometry(exampleTrajectory.getInitialPose()); // Run path following command, then stop at the end. return ramseteCommand.andThen(() -> m_robotDrive.tankDriveVolts(0, 0)); } } ``` ### 謝亞諺 今天在弄防疫門的網路盒,一開始跟以往一樣在Firmware階段很順利,但在Configure階段都會出錯誤,已經照著說明把其他連接停用,但還是很奇妙地出了錯誤,最後在試著各種方法,像在Firmware階段先不打隊伍數字,在Configure,但還是失敗,結果最後連讓電腦連接到網路盒都有問題,不知是網路線接觸不良,還是網路盒的問題。 以下是查到的官網解決辦法,但已經將其他連線排除了 ![](https://i.imgur.com/VOFji94.png) ### 吳玠廷 消毒門的網路盒一開始遇到了網路線接觸不良的問題但是在configure的時候卻會顯示錯誤,根據網路上的說法是無法把網路盒連到筆電的ip其中可能的原因是有網路已經連到那個ip以至於無法順利設定連接,我們也試著把除了乙太網路的連接方式都關掉,也確定沒有任何網路再干擾,卻還是不能連...