001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.wpilibj.smartdashboard; 006 007import edu.wpi.first.math.geometry.Rotation2d; 008import edu.wpi.first.networktables.DoubleEntry; 009import edu.wpi.first.networktables.NetworkTable; 010import edu.wpi.first.networktables.StringEntry; 011import edu.wpi.first.networktables.StringPublisher; 012import edu.wpi.first.networktables.StringTopic; 013import edu.wpi.first.wpilibj.util.Color8Bit; 014 015/** 016 * Ligament node on a Mechanism2d. A ligament can have its length changed (like an elevator) or 017 * angle changed, like an arm. 018 * 019 * @see Mechanism2d 020 */ 021public class MechanismLigament2d extends MechanismObject2d { 022 private StringPublisher m_typePub; 023 private double m_angle; 024 private DoubleEntry m_angleEntry; 025 private String m_color; 026 private StringEntry m_colorEntry; 027 private double m_length; 028 private DoubleEntry m_lengthEntry; 029 private double m_weight; 030 private DoubleEntry m_weightEntry; 031 032 private static String kSmartDashboardType = "line"; 033 034 /** 035 * Create a new ligament. 036 * 037 * @param name The ligament name. 038 * @param length The ligament length. 039 * @param angle The ligament angle in degrees. 040 * @param lineWidth The ligament's line width. 041 * @param color The ligament's color. 042 */ 043 public MechanismLigament2d( 044 String name, double length, double angle, double lineWidth, Color8Bit color) { 045 super(name); 046 setColor(color); 047 setLength(length); 048 setAngle(angle); 049 setLineWeight(lineWidth); 050 } 051 052 /** 053 * Create a new ligament with the default color (orange) and thickness (6). 054 * 055 * @param name The ligament's name. 056 * @param length The ligament's length. 057 * @param angle The ligament's angle relative to its parent in degrees. 058 */ 059 public MechanismLigament2d(String name, double length, double angle) { 060 this(name, length, angle, 10, new Color8Bit(235, 137, 52)); 061 } 062 063 @Override 064 public void close() { 065 super.close(); 066 if (m_typePub != null) { 067 m_typePub.close(); 068 } 069 if (m_angleEntry != null) { 070 m_angleEntry.close(); 071 } 072 if (m_colorEntry != null) { 073 m_colorEntry.close(); 074 } 075 if (m_lengthEntry != null) { 076 m_lengthEntry.close(); 077 } 078 if (m_weightEntry != null) { 079 m_weightEntry.close(); 080 } 081 } 082 083 /** 084 * Set the ligament's angle relative to its parent. 085 * 086 * @param degrees the angle in degrees 087 */ 088 public final synchronized void setAngle(double degrees) { 089 m_angle = degrees; 090 if (m_angleEntry != null) { 091 m_angleEntry.set(degrees); 092 } 093 } 094 095 /** 096 * Set the ligament's angle relative to its parent. 097 * 098 * @param angle the angle 099 */ 100 public synchronized void setAngle(Rotation2d angle) { 101 setAngle(angle.getDegrees()); 102 } 103 104 /** 105 * Get the ligament's angle relative to its parent. 106 * 107 * @return the angle in degrees 108 */ 109 public synchronized double getAngle() { 110 if (m_angleEntry != null) { 111 m_angle = m_angleEntry.get(); 112 } 113 return m_angle; 114 } 115 116 /** 117 * Set the ligament's length. 118 * 119 * @param length the line length 120 */ 121 public final synchronized void setLength(double length) { 122 m_length = length; 123 if (m_lengthEntry != null) { 124 m_lengthEntry.set(length); 125 } 126 } 127 128 /** 129 * Get the ligament length. 130 * 131 * @return the line length 132 */ 133 public synchronized double getLength() { 134 if (m_lengthEntry != null) { 135 m_length = m_lengthEntry.get(); 136 } 137 return m_length; 138 } 139 140 /** 141 * Set the ligament color. 142 * 143 * @param color the color of the line 144 */ 145 public final synchronized void setColor(Color8Bit color) { 146 m_color = String.format("#%02X%02X%02X", color.red, color.green, color.blue); 147 if (m_colorEntry != null) { 148 m_colorEntry.set(m_color); 149 } 150 } 151 152 /** 153 * Get the ligament color. 154 * 155 * @return the color of the line 156 */ 157 public synchronized Color8Bit getColor() { 158 if (m_colorEntry != null) { 159 m_color = m_colorEntry.get(); 160 } 161 int r = 0; 162 int g = 0; 163 int b = 0; 164 if (m_color.length() == 7 && m_color.charAt(0) == '#') { 165 try { 166 r = Integer.parseInt(m_color.substring(1, 3), 16); 167 g = Integer.parseInt(m_color.substring(3, 5), 16); 168 b = Integer.parseInt(m_color.substring(5, 7), 16); 169 } catch (NumberFormatException e) { 170 r = 0; 171 g = 0; 172 b = 0; 173 } 174 } 175 return new Color8Bit(r, g, b); 176 } 177 178 /** 179 * Set the line thickness. 180 * 181 * @param weight the line thickness 182 */ 183 public final synchronized void setLineWeight(double weight) { 184 m_weight = weight; 185 if (m_weightEntry != null) { 186 m_weightEntry.set(weight); 187 } 188 } 189 190 /** 191 * Get the line thickness. 192 * 193 * @return the line thickness 194 */ 195 public synchronized double getLineWeight() { 196 if (m_weightEntry != null) { 197 m_weight = m_weightEntry.get(); 198 } 199 return m_weight; 200 } 201 202 @Override 203 protected void updateEntries(NetworkTable table) { 204 if (m_typePub != null) { 205 m_typePub.close(); 206 } 207 m_typePub = 208 table 209 .getStringTopic(".type") 210 .publishEx( 211 StringTopic.kTypeString, "{\"SmartDashboard\":\"" + kSmartDashboardType + "\"}"); 212 m_typePub.set(kSmartDashboardType); 213 214 if (m_angleEntry != null) { 215 m_angleEntry.close(); 216 } 217 m_angleEntry = table.getDoubleTopic("angle").getEntry(0.0); 218 m_angleEntry.set(m_angle); 219 220 if (m_lengthEntry != null) { 221 m_lengthEntry.close(); 222 } 223 m_lengthEntry = table.getDoubleTopic("length").getEntry(0.0); 224 m_lengthEntry.set(m_length); 225 226 if (m_colorEntry != null) { 227 m_colorEntry.close(); 228 } 229 m_colorEntry = table.getStringTopic("color").getEntry(""); 230 m_colorEntry.set(m_color); 231 232 if (m_weightEntry != null) { 233 m_weightEntry.close(); 234 } 235 m_weightEntry = table.getDoubleTopic("weight").getEntry(0.0); 236 m_weightEntry.set(m_weight); 237 } 238}