001/** 002 * Copyright 2024 The Space Cookies : Girl Scout Troop #62868 and FRC Team #1868 003 * Open Source Software; you may modify and/or share it under the terms of 004 * the 3-Clause BSD License found in the root directory of this project. 005 */ 006 007package tagalong.commands.aim; 008 009import edu.wpi.first.math.geometry.Pose2d; 010import edu.wpi.first.math.geometry.Translation2d; 011import java.util.function.DoubleSupplier; 012import java.util.function.Supplier; 013import tagalong.commands.base.PivotToDynamicCmd; 014import tagalong.math.AlgebraicUtils; 015import tagalong.subsystems.TagalongSubsystemBase; 016import tagalong.subsystems.micro.augments.PivotAugment; 017 018/** 019 * Command that continuously points at a target in 2d space while compensating for the current 020 * rotation of the robot. Since this is strictly rotational targeting give robot position as (X, Y) 021 * pose 022 */ 023public class PivotAimAtYawCompCmd<T extends TagalongSubsystemBase & PivotAugment> 024 extends PivotToDynamicCmd<T> { 025 @SuppressWarnings("unused") 026 /** 027 * Target to aim at 028 */ 029 private final Translation2d _target; 030 @SuppressWarnings("unused") 031 /** 032 * Robot location supplier (x, y, theta) 033 */ 034 private final Supplier<Pose2d> _locationSupplier; 035 036 /** 037 * Transform position into an optimal path angle to target, compensates for the current robot yaw 038 * while respecting the system's positional limits 039 * 040 * @param location Current robot location supplier 041 * @param pivotPosition Pivot position supplier 042 * @param target Target to aim at's location 043 * @param pivotMinRot pivots minimum position in rotations 044 * @param pivotMaxRot pivots maximum position in rotations 045 * @return Optimal path target angle for the pivot 046 */ 047 protected static DoubleSupplier positionTransform( 048 Supplier<Pose2d> location, 049 DoubleSupplier pivotPosition, 050 final Translation2d target, 051 double pivotMinRot, 052 double pivotMaxRot 053 ) { 054 return () -> { 055 Pose2d curPos = location.get(); 056 // Robot to target 057 double toTargetRot = 058 Math.atan((target.getX() - curPos.getX()) / (target.getY() - curPos.getY())); 059 // Delta between front of robot and that target, aka the target angle for the system 060 double delta = (toTargetRot - curPos.getRotation().getRotations()) % 1.0; 061 delta += delta < 0 ? 1.0 : 0; 062 063 // Take the shortest path to that position 064 double scopedAngle = AlgebraicUtils.placeInScopeRot(pivotPosition.getAsDouble(), delta); 065 if (scopedAngle > pivotMaxRot) { 066 scopedAngle -= 1.0; 067 } 068 if (scopedAngle < pivotMinRot) { 069 scopedAngle += 1.0; 070 } 071 072 return AlgebraicUtils.clamp(scopedAngle, pivotMinRot, pivotMaxRot); 073 }; 074 } 075 076 /** 077 * Minimal constructor with default parameters 078 * 079 * @param id Integer ID of the pivot microsystem inside the 080 * Tagalong Subsystem 081 * @param pivot Tagalong Subsystem containing a pivot microsystem 082 * @param positionSupplier Supplies the current robot position position 083 * @param target Unmoving 2-dimensional target location 084 */ 085 public PivotAimAtYawCompCmd( 086 int id, T pivot, Supplier<Pose2d> positionSupplier, Translation2d target 087 ) { 088 this(id, pivot, positionSupplier, target, true); 089 } 090 091 /** 092 * Minimal constructor with default parameters 093 * 094 * @param pivot Tagalong Subsystem containing a pivot microsystem 095 * @param positionSupplier Supplies the current robot position position 096 * @param target Unmoving 2-dimensional target location 097 */ 098 public PivotAimAtYawCompCmd(T pivot, Supplier<Pose2d> positionSupplier, Translation2d target) { 099 this(pivot, positionSupplier, target, true); 100 } 101 102 /** 103 * Constructor that creates the command with the below parameters. 104 * 105 * @param id Integer ID of the pivot microsystem inside the 106 * Tagalong Subsystem 107 * @param pivot Tagalong Subsystem containing a pivot microsystem 108 * @param positionSupplier Supplies the current robot position position 109 * @param target Unmoving 2-dimensional target location 110 * @param holdPositionAfter If the pivot should hold position when the command completes 111 * @param maxVelocityRPS The maximum velocity of the pivot, in rotations per second, during 112 * this command 113 */ 114 public PivotAimAtYawCompCmd( 115 int id, 116 T pivot, 117 Supplier<Pose2d> positionSupplier, 118 Translation2d target, 119 boolean holdPositionAfter, 120 double maxVelocityRPS 121 ) { 122 super( 123 id, 124 pivot, 125 positionTransform( 126 positionSupplier, 127 pivot.getPivot(id)::getPivotPosition, 128 target, 129 pivot.getPivot(id)._minPositionRot, 130 pivot.getPivot(id)._maxPositionRot 131 ), 132 holdPositionAfter, 133 maxVelocityRPS 134 ); 135 _target = target; 136 _locationSupplier = positionSupplier; 137 } 138 139 /** 140 * Constructor that creates the command with the below parameters. 141 * 142 * @param pivot Tagalong Subsystem containing a pivot microsystem 143 * @param positionSupplier Supplies the current robot position position 144 * @param target Unmoving 2-dimensional target location 145 * @param holdPositionAfter If the pivot should hold position when the command completes 146 * @param maxVelocityRPS The maximum velocity of the pivot, in rotations per second, during 147 * this command 148 */ 149 public PivotAimAtYawCompCmd( 150 T pivot, 151 Supplier<Pose2d> positionSupplier, 152 Translation2d target, 153 boolean holdPositionAfter, 154 double maxVelocityRPS 155 ) { 156 super( 157 pivot, 158 positionTransform( 159 positionSupplier, 160 pivot.getPivot()::getPivotPosition, 161 target, 162 pivot.getPivot()._minPositionRot, 163 pivot.getPivot()._maxPositionRot 164 ), 165 holdPositionAfter, 166 maxVelocityRPS 167 ); 168 _target = target; 169 _locationSupplier = positionSupplier; 170 } 171 172 /** 173 * Constructor that creates the command with the below parameters. 174 * 175 * @param id Integer ID of the pivot microsystem inside the 176 * Tagalong Subsystem 177 * @param pivot Tagalong Subsystem containing a pivot microsystem 178 * @param positionSupplier Supplies the current robot position position 179 * @param target Unmoving 2-dimensional target location 180 * @param holdPositionAfter If the pivot should hold position when the command completes 181 */ 182 public PivotAimAtYawCompCmd( 183 int id, 184 T pivot, 185 Supplier<Pose2d> positionSupplier, 186 Translation2d target, 187 boolean holdPositionAfter 188 ) { 189 this( 190 id, pivot, positionSupplier, target, holdPositionAfter, pivot.getPivot(id)._maxVelocityRPS 191 ); 192 } 193 194 /** 195 * Constructor that creates the command with the below parameters. 196 * 197 * @param pivot Tagalong Subsystem containing a pivot microsystem 198 * @param positionSupplier Supplies the current robot position position 199 * @param target Unmoving 2-dimensional target location 200 * @param holdPositionAfter If the pivot should hold position when the command completes 201 */ 202 public PivotAimAtYawCompCmd( 203 T pivot, Supplier<Pose2d> positionSupplier, Translation2d target, boolean holdPositionAfter 204 ) { 205 this(pivot, positionSupplier, target, holdPositionAfter, pivot.getPivot()._maxVelocityRPS); 206 } 207}