Hey guys our team has been trying to program PID, we are pretty knew to java.We don’t have any errors in the code but when ever we try deploying the code the light for Robot Code is red
Here is our Riolog
ERROR 1 Unhandled exception: java.lang.NullPointerException frc.robot.commands.Move.(Move.java:26)
ERROR 1 The startCompetition() method (or methods called by it) should have handled the exception above. edu.wpi.first.wpilibj.RobotBase.startRobot(RobotBase.java:276)
Warning at edu.wpi.first.wpilibj.RobotBase.startRobot(RobotBase.java:274): Robots should not quit, but yours did!
Here is my GitHub
On line 25 you’re declaring an encoder but not initializing it, so it’s null when line 26 tries to use it. You need to create the encoder with
private Encoder encoder = new Encoder(1,2); or similar (where 1 and 2 are the ports the encoder is plugged into).
You’re going to need to give more information than that. Did the backtrace change? It could easily be crashing somewhere else. The backtrace is extremely helpful for finding where in your code the problem is. If it’s also a null pointer exception, try to fix it yourself similar to how you fixed the issue with the encoder.
Im new to programming i never heard of backtrace and i dont know how to use it.
The backtrace is the thing you posted initially – it literally traces back the method calls that were made when the error occurred. If you read through that error, it tells you what the error was and what line it happened on, and where that method was called from. If that backtrace changed, then your error has also changed.
Back trace, stack trace, exception are basically the same as saying show us your error.
Ok thaks i will look into that when i have the laptop with me.
Without looking at your stacktrace, but looking through your code, I suspect the issue may be that you’re trying to initialize an encoder on the same ports twice. In your DriveTrain subsystem code, you initialize an encoder on ports 0 and 1 – if that’s the same encoder you tried to initialize in your command, then this could be causing the error.
Generally speaking, it’s good form to keep your sensors initialized with the subsystems they belong to. This will allow you to use the encoder values in multiple different commands if you need to do that later, and it also logically makes more sense with object-oriented principles – each subsystem should “own” all of the hardware (motors, sensors) associated with it.
So to use that encoder in your command, rather than re-initializing your encoder in your command, you could write a public method
getEncoderFeet() in your DriveTrain subsystem, depending on what values you want to use in your commands. This method could just get the values from the encoder the subsystem already owns. Then, your command would not need to separately keep track of
kDriveTick2Feet or the encoder object.
Also, some other things you should think about:
Be aware that when you set variables outside of functions in your commands, those values will be set upon construction of the object. The
initialize() method is called when the command is just about to run. This is not the same thing, even though sometimes the result may be the same.
For example, think about what happens if you create a
CommandGroup where you want to run a couple of commands, one after the other (see here if you haven’t ever done this before). In this case, you’re initializing the commands all at the same time, which is when the CommandGroup is first initialized – not when the command is first about to be run. However, sometimes the outputs of each command change the inputs for the next stage.
For example, with your code, what would happen if you had a Move command followed by a turn, then another Move command? How would the encoder values change throughout the first Move command? What will the starting value of your
sensorPosition variable in your second Move command be? What should it be?
Think about how you expect your command code to flow. The command-based architecture essentially will run the constructor code first, then the
initialize() method, then regularly run
isFinished() returns true, then run
double sensorPosition = encoder.get() * kDriveTick2Feet;
double error = setpoint - sensorPosition;
double outputSpeed = kP * error;
What is the purpose of those lines of code? What are you calculating? When are you using those values? When should those values be updated, and are they being updated at the correct time?
- This one is fairly straightforward: as far as I can see, your Move command is never actually commanding your drivetrain to move (there’s no setting of motor power in there right now). Is this what you want to do? If not, where would you set motor power? What would you set the power to?
I have been watching a PID video made by 0 to autonomous and i just followed the video and tweeked somethings because we are new to using PID
That’s fine, and while I’m not familiar with that video series, tutorials like that are often a great place to start. However, it’s still good to ask yourself these questions about how the internals of what you just wrote work – after all, you most likely won’t be able to use just the direct tutorial code on your competition robot, so you’ll have to make modifications. Also, inevitably, whoever wrote the tutorial will do some things differently than your team – even if you’re starting from scratch, combining things from different tutorials will often get you differing code styles in different parts of your code.
The more you try to understand why things are done one way or the other, the more easily you’ll be able to make changes when you need to – whether it’s for consistency or to modify functionality.
If you want me to further explain some things I said to ask yourself in my previous comment, feel free to ask more questions.
ok i now have access to our robotics laptop here is my stack trace
Executing task: gradlew deploy -PteamNumber=6390 --offline -Dorg.gradle.java.home=“C:\Users\Public\frc2019\jdk” <
Driver Station reported IP: 10.63.90.2
Discovering Target roborio
Using [email protected]:22 for target roborio
-C-> mkdir -p @ /home/lvuser/deploy
1 file(s) are up-to-date and were not deployed
-C-> if [[ -f “/usr/local/frc/JRE/bin/java” ]]; then echo OK; else echo MISSING; fi @ /tmp
-C-> . /etc/profile.d/natinst-path.sh; /usr/local/frc/bin/frcKillRobot.sh -t 2> /dev/null @ /home/lvuser
1 file(s) are up-to-date and were not deployed
-C-> echo '/usr/local/frc/JRE/bin/java -Djava.library.path=/usr/local/frc/third-party/lib -jar “/home/lvuser/LetsTryJava.jar” ’ > /home/lvuser/robotCommand @ /home/lvuser
-C-> chmod +x /home/lvuser/robotCommand; chown lvuser /home/lvuser/robotCommand @ /home/lvuser
-C-> chmod +x “/home/lvuser/LetsTryJava.jar”; chown lvuser “/home/lvuser/LetsTryJava.jar” @ /home/lvuser
-C-> sync @ /home/lvuser
-C-> . /etc/profile.d/natinst-path.sh; /usr/local/frc/bin/frcKillRobot.sh -t -r 2> /dev/null @ /home/lvuser
-C-> sed -i -e ‘s/^StartupDLLs/;StartupDLLs/’ /etc/natinst/share/ni-rt.ini @ /home/lvuser
42 file(s) are up-to-date and were not deployed
-C-> chmod -R 777 “/usr/local/frc/third-party/lib” || true; chown -R lvuser:ni “/usr/local/frc/third-party/lib” @ /usr/local/frc/third-party/lib
-C-> ldconfig @ /usr/local/frc/third-party/lib
Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use ‘–warning-mode all’ to show the individual deprecation warnings.
See Command-Line Interface
BUILD SUCCESSFUL in 16s
12 actionable tasks: 8 executed, 4 up-to-date
i have no errors so im not sure what the issue is
First error I see is in your Move file, when you initiate the encoder variable, you never completed the statement. It would need to be
private Encoder encoder = new Encoder(port1, port2);
Next thing, I personally would not do your subsystem this way. The TalonSRX class is not correct, it is a WPI_TalonSRX. If I am correct the TalonSRX is for non-FRC teams. A link to my code is a suggestion of how I setup my DriveTrain subsystem https://github.com/frc-4012/FRC4012-PowerupRewrite/blob/master/src/main/java/frc/robot/subsystems/drive/DriveTrain.java
This is not correct. WPI_TalonSRX is a subclass of TalonSRX and adds some additional features to Talons to make them more WPI friendly.
If you’re wondering how to choose between the two, use WPI_TalonSRX if you need motor safety or need it to implement SpeedController, otherwise just use TalonSRX. If there are other features that the WPI_TalonSRX has please correct me.
Personally, we haven’t needed WPI_TalonSRX because we don’t use any of its features.
I still have not been able to figure out why i am getting the erroros
Hmm, earlier you stated that the error was not present anymore. What does the stack-trace show now?
I have posted my stacktrace above i just had no errors or warnings in my problems section