ROBOTC V4.52

We pushed out ROBOTC V4.52 today (Dec 7 2015).

There are a few interesting features included for teams programming the cortex using ROBOTC.

Datalogging.
This is a new feature that enables you to monitor parameters such as motor power and sensor values and save that information off in a excel compatible file. This can be used in two different ways.

  1. Background polling
    This allows you to define up to 8 different parameters to be monitored in the background. Lets say you were working on a PID control loop and you wanted to be able to plot motor control values against time. You are now able to monitor those without adding any additional code or debug statements to your code. A new debug window will show these values as they change and can be saved as a CSV file.

  2. User polling
    You can add statements to your code that will save any value and add a timestamp. See the sample program provided with ROBOTC for more details.

Motor velocity
For motors that have an IME attached you can now see the motor velocity in the motors debug window and also retrieve that using a new command, getMotorVelocity. The velocity returned is determined inside the IME, it’s not necessarily any more accurate than other techniques used and may still need filtering, however, as a quick check when using the debugger it’s quite useful.

User I2C sensors
This only applies to VEXU teams. We now have the ability to read any compatible (ie. electrically compatible with a non-conflicting address) I2C device that is connected to the cortex. These can be used in addition to any IMEs that may be attached. See the example provided with the new version for more details or contact me directly.

There are also numerous bug fixes, see the blog post here.
http://www.robotc.net/blog/2015/12/07/robotc-vex-4-52/#more-4849

Awesome! The Cortex comes to the science lab. Thank you! Thank you!

This is an initial implementation and still has a few “rough edges”, it only made it into the cortex build very recently. Robomatter is always looking for constructive feedback so let us know what you think of the new features. This functionality is also available on the other platforms we support including VexIQ.

ok so I am a little confused about how to use the data logger, what exactly does each command do, I am confused here, does the command
datalogAddValue(); just add one value to the data stream, or does it add a value continually to the stream. for example, if I said

datalogAddValue(0,velocity);
would it constantly print the value of the variable velocity to the data logger, or would it just print the value once, the same question goes for the variant of this command with timestamp.

Also, with those 8 series you set up in the motor and sensors set up window, can you use those to output a variable there, that is not related directly to a motor or sensor. for example I use an exponentially weighted moving average for my flywheel velocity, how would I output that to the data log

finally, how do I use this data log, do I have to have my computer hooked up to my robot using the serial to usb cable, and once I have the data how do I save it to the CSV file

sorry for all the questions I’ve never used this before and I would really like to use this to help tune the PID loops on my robot

I would suggest looking at the datalogging sample program found
File → Open Sample Program → VEX2 → Advanced → datalogging

Pasted here for convenience.

/*---------------------------------------------------------------------------*/
/*        Module:     Datalog_example.c                                      */
/*        Author:     James Pearman                                          */
/*        Created:    12 Nov 2015                                            */
/*        Platform:   Vex-IQ, EV3, NXT                                       */
/*        RC Version: 4.51                                                   */
/*                                                                           */
/*        Revisions:                                                         */
/*                    1.00  12 Nov 2015 - Initial release                    */
/*---------------------------------------------------------------------------*/
/*                                                                           */
/*        Description:                                                       */
/*                                                                           */
/*        This sample code demonstrates the use of dataloging commands       */
/*---------------------------------------------------------------------------*/
/*                                                                           */

#if defined(VexIQ) || defined(EV3) || defined(NXT) || defined(VEX2)

// Global variables used by the sample code
int   global_1 = 0;
int   global_2 = 0;
int   global_3 = 0;

// We have 8 possible places to store data, we call each one a datalog series
// This example uses the first three to store values.
#define   DATALOG_SERIES_0    0
#define   DATALOG_SERIES_1    1
#define   DATALOG_SERIES_2    2

/*---------------------------------------------------------------------------*/
task main()
{
    int loops = 0;

    // Clear old data
    datalogClear();

    while(1)
        {
        // datalogAddValue adds one row to the datalog but does not time stamp the value
        datalogAddValue( DATALOG_SERIES_0, loops++ );


        // datalogAddValue when surrounded by datalogDataGroupStart and datalogDataGroupEnd
        // adds several values to one row of the datalog with a common time stamp
        datalogDataGroupStart();
        datalogAddValue( DATALOG_SERIES_0, global_1++ );
        datalogAddValue( DATALOG_SERIES_1, global_2++ );
        datalogAddValue( DATALOG_SERIES_2, global_3++ );
        datalogDataGroupEnd();

        // datalogAddValueWithTimeStamp adds one row that is time stamped
        // the following statement is equivalent to the code
        //
        // datalogDataGroupStart();
        // datalogAddValue( DATALOG_SERIES_0, global_1++ );
        // datalogDataGroupEnd();
        //
        datalogAddValueWithTimeStamp( DATALOG_SERIES_0, global_1++ );



        // More examples of datalogAddValueWithTimeStamp
        // The small delay is just for demonstration purposes
        wait1Msec(10);
        datalogAddValueWithTimeStamp( DATALOG_SERIES_1, global_2++ );
        wait1Msec(10);
        datalogAddValueWithTimeStamp( DATALOG_SERIES_2, global_3++ );

        // loop delay
        wait1Msec(50);
        }
}

/*---------------------------------------------------------------------------*/
#else
#warning "Invalid platform selected for this sample program"
#endif

We had a small bug creep through in 4.52, delete these two lines from you competition code for now or you will get compile errors.

#pragma autonomousDuration(20)
#pragma userControlDuration(120)

Does it affect how the robot performs on the field? Also, after the update, i had more than those 2 errors(a bunch of define errors)

It does not affect how the robot performs, those statements are left over from the days of the PIC and radios.

Can you send me the code in a private message so I can see the other errors?

Any instructions on how to downgrade RobotC?

So we had a little snafu with the new version of ROBOTC yesterday. A small change we had made to the compiler caused the problem when compiling code with the old autonomousDuration and userControlDuration pragmas included, how we missed this in regression testing I don’t know, but we did and I apologize for that.

We pushed an update out this morning to fix that bug, you will need to download and reinstall again if you already updated to V4.52.

The new version has a full build number of 4.52.0.9067 (shown in windows properties) and a build date of Dec 8.

James,

Could you give some more details on how getMotorVelocity() is calculated internally?

Is it’s accuracy a subject to integer round off and how much?

Would any I2C communication delays cancel themselves out?

So the information on the IME is here.

Everytime the IME is polled it returns both the encoder count and the “velocity” data. I was going to return this raw data when getMotorVelocity was called but decided to do a simple conversion to rpm so the debug window display was more useful. Conversion uses integer math, there is no filtering, we just convert the last value was that returned from the IME. For the benefit of students reading this the math is as follows.

The above post has the conversion explained like this.
*

A bit of a mouthful that can distill down to the following integer expression (for a torque geared 393)

RPM = (15625 x 60000) / (velocity * 78400) or
RPM = 937500000 / (velocity * 78400)

15625 is 1/0.000064
78400 is 39.2 * 2 * 1000

This is ok but causes some overflow problems with the 32 bit math when velocity gets large. To mitigate this we divide the constants by 4.

RPM = 234375000 / (velocity * 19600)

The constant 19600 is changed based on the motor type selected (and I actually see a small typo in one of them :frowning: )

So this rpm value is an instantaneous velocity that the IME measured, it will I’m sure have some jitter and need filtering. You could probably use the getEncoderAndTimestamp function to get the last time we polled the encoder and received the velocity data. Again, the primary reason for including this was so the debugger would show motor speed.

Hope this helps.

Thanks for the info!

So, if I understand it correctly, when motor is running at its nominal speed velocity reading out of IME should be ~119.578 (64 usec intervals). And, if motor is running at half nominal speed the reading is ~239.156 intervals.

Since it got to be integer IME firmware will round or, more likely, truncate it to 119 and 239 respectively. This gives up to 1% potential error at max speed and <0.5% error for half the nominal speed.

When RobotC firmware converts this number to RPMs it could introduce another 0.5% rounding error when returning ~100 rpms or even more when returning values around ~50 RPMs.

If you use traditional methods you either have delayed results if using large sample interval or face large errors (for example, measuring 14 encoder ticks over 20 msec interval could introduce both 1 encoder and 1 timer tick uncertainty).

So, short of doing fancy filter math, getMotorVelocity() is very convenient solution with nearly instant results and good expected accuracy (<1.5% error). Regardless of the actual motor type I will always list it as turbo to the RobotC to reduce the second rounding error.

Also, correct me if I am wrong, with one IME connected, RobotC will be polling it every millisecond, so encoder “distance” reading has up to 1 encoder and 1 timer tick inaccuracy making getEncoderAndTimestamp() useful over larger intervals.

See the pretty pictures in this post.

Any plans to allow datalogging results to be saved to non-volatile memory? I find it useful to be able to review data from a match after the robot has been through a power cycle.

We have no plans to implement this as part of ROBOTC, there are issues writing to flash memory when the code is also running from that same memory. However, in my pre-robomatter life I wrote a library that would allow you to do this, there are drawbacks but it can achieve what you want if used carefully.

This is not endorsed in anyway by Robomatter, it has not been tested with the latest version of ROBOTC, use at your own risk. See this old thread.

Just wanted to add here that ROBOTC 4.54 is now available.

http://www.robotc.net/blog/2016/08/01/robotc-vex-4-54/

Yes, it’s been available for a couple of days. It is similar to the V4.53 preview that’s been available for a few weeks with some additional support for VexIQ.

When I get a chance I will post some details on some of the more subtle features we added that apply to the cortex.

Only noticed today when the email went out. The main things that jumped out were obviously the graphing now being in a general release and
Deleting a file from the File Utility was not possible, this has been fixed.
which is nice. It was always one of those things that just confused me every time.

Of course graphical getting variables changes the amount of things you can do in graphical by an order of magnitude.

@jpearman
Where can I find the documentation on datalogging?
It isn’t in the API reference. Also, I heard that there was a function that let the user override the LCD displaying a timer, is that true?