Printing Float to Dashboard

I’m looking at printing the value of the joystick y axis to the screen.


DriverStation *ds;
DriverStationLCD *dsLCD;
Joystick *driveController;

RobotDemo(void)
{
    ds = DriverStation::GetInstance();
    dsLCD = DriverStationLCD::GetInstance();
    driveController = new Joystick(1);
}

void OperatorControl(void)
{
    GetWatchdog().SetEnabled(true);
    while (IsOperatorControl())
    {
        GetWatchdog().Feed();
        dsLCD->Printf(DriverStationLCD::kUser_Line4, 1, driveController->GetY());
        dsLCD->UpdateLCD();
    }
}

Is there something that needs to be included?? is there a ToString() like there is in java???

Also is there string concatenation that you can add two strings together?? "Left Drive: " + driverController->GetY()

Your ToString() comment made my day.

If you want to write a float to a string you can use some of the following methods.


float my_float = 123.456f;
char line_buffer[22];
sprintf(line_buffer, "value: %.2f", my_float);

// or

#include <sstream>

float my_float = 123.456f;
std::stringstream ss("value: ");
ss.precision(2);
ss << my_float;
std::string line_buffer = ss.str();

We ran into this exact same problem yesterday and after searching online for an hour and getting nowhere on the cocanate issue i finally found this link which was immensely helpful.

http://www.cppreference.com/wiki/c/io/printf

Like the poster above me showed, I kept finding convoluted methods to do something that is extremely trivial in other program languages. After evaluating the DriverStationLCD class and seeing it was probably inheriting most of its features from the C++ printf class I figured I would give the %f thing in the link above a try. When we tried it this evening it worked perfect.

Your code might look like this as an example:

dsLCD->Printf(DriverStationLCD::kUser_Line4, 1,“Joystick Y axis: %f”, driveController->GetY());

The %f is a placeholder waiting for a float variable to be passed. Hope this helps you out.

printf isn’t a class! printf is a function! Also other programming languages (I assume you mean Java, C#, VB, etc) probably use printf or at least a function similar to the one C uses. In fact, float to string is trivial.

For reference the following code DOES work :slight_smile:


char line_buffer[22];

sprintf(line_buffer, "Y: %.2f", driveController->GetY());
dsLCD->Printf(DriverStationLCD::kUser_Line2, 1, line_buffer);

Thanks for everyones help. Note: just like every language there is 100 ways to do every problem. . . I just really couldn’t get anything to work. . . Not saying this is the best way but it works to test out values

That is most definitely NOT the best way to call DriverStationLCD:: Printf(). If you are not careful, you can easily overrun the end of your line_buffer, and most likely corrupt other memory, making for a very hard to debug problem.

The best way is to use the Printf() method as it was intended: put the format string in the argument list, followed by your variable(s):


dsLCD->Printf(DriverStationLCD::kUser_Line2, 1, "Y: %.2f", driveController->GetY());

If you take a look at the source code for the Printf() method, you will see that it goes to great pains to make sure it does not write more than 21 bytes to its internal line buffer.

HTH.

Method, class, function, whatever. All this stuff may sound trivial to those that program all the time, but I can assure you that to those that learned to program old school when there was only the subroutine and the function, all this object oriented stuff is anything but trivial.

Please remember that when a person asks for help, he has made himself vulnerable and doesn’t want to be attacked, he wants help. I tried to help him with the thing that worked for me when I ran into this exact problem. I do appreciate the correction on your part and I will refer to printf as a function from now on. Just remember gracious professionalism is the overriding goal of FIRST please.

I wonder why they decided to use printf instead of the C++ streams. this would be much easier, and more modular, you don’t need to know what you are putting in, and you could even (if it implements it) output a whole joystick
dsLCD.Printf(line,collum, “JoyY: %f”,stick.GetY);
vs
dsLCD(line,collum)<<“JoyY:”<<stick.GetY();

I think C programmers maintain WPI library’s C++ version so they use familiar functions.

Also using an std::stringstream would be a great idea. However, I would just remove the column index completely as you can use seekp().

Or sometimes us old-time C programmers know what is efficient and what is not. Remember, although the cRio is lightyears ahead of the old IFI controller, we are still programming on an embedded system, not a desktop PC. Using the C++ iostream library requires your program to bring in a whole bunch of extra code, most of which will never be used in our implementations. The extra processing required to do all the buffer manipulation that gives you that smooth I/O redirection interface is not really noticed in a program running on a desktop PC, but for a finely-tuned embedded program, it can be the difference between smooth operation of your control loops and erratic, unexpected behaviors.

Especially for a function like writing to the Driver Station, you want to keep things as simple and fast as possible, so as not to slow down or impede communications with the robot.

So sometimes the old ways are better not because they are “familiar”, but instead are “just better” for the particular task at hand.

Now you kids get off my lawn with that crazy “<<” stuff! :smiley:

Strange, “WPILib.h” imports iostream… :stuck_out_tongue:

Ah - but clever programmers know better than to take the lazy way out and include “WPILib.h”. The most efficient way to use the WPILib library is to not #include the “kitchen sink”, like WPILib.h does, but to #include only the headers that you actually need.

You will notice that nowhere else in the WPILib source code is either WPILib.h or iostream.h included. The iostream.h inclusion in WPILib.h is simply there for convenience, not because it is required.

I’m really not against the use of iostream.h (or <<iostream>>) where it makes sense. It’s just that on our robots, the few places where it might actually be useful do not justify the overhead required.

Frankly, I am a little lost on what’s going on. I searched Chief Delphi and found this thread (to my joy::safety::).

I wonder where the program prints to on the driver station dashboard? Is it under the “User Messages” box? (I am a freshman, so please explain :])

THANKS!:slight_smile:

The standard out is written to the NetConsole. Look at C++ documentation for details.