Results 1 to 11 of 11

Thread: Heart Rate Enhanced Object Strobe

  1. #1
    Tuner in Training
    Join Date
    May 2015
    Posts
    28

    Heart Rate Enhanced Object Strobe

    Hi:

    I'm trying to use the strobe function in an enhanced object to blink the driver heart rate, the only example of the strobe function is in the Lap Time Enhanced object where it strobe is written as:

    if(FlashInterval <= 0.0 || Strobe(FlashInterval))
    Visible = true;
    else
    Visible = false;

    From this for Heart Rate I'm thinking that following should work:

    if (DataValue > 0 && strobe(60/DataValue)
    Visible = true;
    else
    Visible = false

    Basically for a 120BPM this should flicker the light every 0.5s, no? Are there any more examples on how to make this work? Even when I replace the strobe with strobe(1) i don't get any blinking.

    TIA.

    Tim

  2. #2
    Tuner in Training
    Join Date
    May 2015
    Posts
    28
    Is this doable? Is there a better example of strobe() anywhere to work from?

  3. #3
    HPT Employee Weston@HPTuners's Avatar
    Join Date
    Jul 2014
    Location
    39.735034, -103.894459
    Posts
    868
    The code example you gave above should work... It would cause the "Visible" variable to become true at an interval of 0.5 seconds (2 Hz), when DataValue is 120. Being that you don't get anything when using Strobe(1), you might try double-checking that DataValue is indeed giving correct data (ie your heart rate field is selected for that display object), and that Visible is actually being used to display something.

    The print() command can be very useful for debugging these things, as it will display the current value of one or more variables to the Script Editor's messages at the bottom.

    However, both print(), and the actual preview image, will be tied to the current preview time, so you might find that Strobe() is false when you're in the Script Editor until you go adjust the main preview time and come back.

  4. #4
    Tuner in Training
    Join Date
    May 2015
    Posts
    28
    Sorry, am getting back to this but I'm still not getting this to flash. Does strobe(secs) have to be an integer parameter or will it allow fractional seconds?

    I'm using a brake light style enhanced object with a trigger of 1, where the data values range from 60 to 150 (thus it would always be triggered) but trying to use the strobe to make it flash at approximately the rate of the heart rate. But I only get a solid light. You say above "and that Visible is actually being used to display something" what does that mean? If I set visible to false, does that turn the visibility of the object off or do I need to call a different method to set visibility based on the value of visible? I don't see any functions to set visibility at http://racerender.com/RR3/docs/DispObjEnhanced.html

    To make matters worse, RaceRender is crashing repeatedly when there are compile errors in the script (typos essentially), I'm using the 20170824 build (3.6).

  5. #5
    Tuner in Training
    Join Date
    May 2015
    Posts
    28
    hmm...have it sort of working with this in the foreground script:

    if(Datavalue > 0) { //no short circuit evaluation using &&, causes divide by zero e.g. if(DataValue>0 && strobe(60/DataValue)
    Visible = strobe(60/DataValue);
    }

    if(Visible) {
    DrawDot(CenterX, CenterY, MainColor, Space / 2);
    } else {
    DrawDot(CenterX, CenterY, BackColor, Space / 2);
    }

    But it looks like Strobe() doesn't like a parameter that varies in time; it appears to get confused on whether it should be 1 or 0 once the input parameter changes.

    Here's a sample video where the strobe does no really reflect the frequency of the input signal
    https://www.youtube.com/watch?v=Z7yB...ature=youtu.be

    Thoughts? (other than calculating my own period counter to track visibility)

  6. #6
    Tuner in Training
    Join Date
    May 2015
    Posts
    28
    Trying to implement my own logic to change the color on my own at varying intervals based on the HR data. The logic is pretty simple, calculate a duration based on the new data value, then see from the last toggle time to now is longer than the duration, and if so toggle the light state & update last toggle time. Using the print function seems to re-initialize everything when opening the editor so its hard to debug. Is there a way to advance frames from within the script editor and have the script re-evaluated and display the printed values? Running it outside the editor seems to toggle light state on first execution and then never toggles it back the next time the toggle duration is exceeded.

    SinceLastToggle = SampleTime - LastToggleTime;

    print (SampleTime, LastToggleTime, SinceLastToggle, ToggleDuration, LightState);

    if (DataValue != 0) {
    ToggleDuration = 60 / DataValue;
    }

    if (SinceLastToggle > ToggleDuration) {
    LastToggleTime = SampleTime;
    LightState = !LightState;
    }

    print (SampleTime, LastToggleTime, SinceLastToggle, ToggleDuration, LightState);

    if(LightState) {
    DrawDot(CenterX, CenterY, MainColor, Space / 2);
    } else {
    DrawDot(CenterX, CenterY, BackColor, Space / 2);
    }

  7. #7
    Tuner in Training
    Join Date
    May 2015
    Posts
    28
    Any thoughts Weston?

    Also, is there any means to display an PNG as an object? Would adding the PNG to the resources folder of the Application package allow it to appear in the list of E-Images?

  8. #8
    HPT Employee Weston@HPTuners's Avatar
    Join Date
    Jul 2014
    Location
    39.735034, -103.894459
    Posts
    868
    Quote Originally Posted by leisurehound View Post
    Sorry, am getting back to this but I'm still not getting this to flash. Does strobe(secs) have to be an integer parameter or will it allow fractional seconds?
    The parameter for Strobe() does not need to be an integer. It will try to use any interval/period length you give it.

    [quote]You say above "and that Visible is actually being used to display something" what does that mean? If I set visible to false, does that turn the visibility of the object off or do I need to call a different method to set visibility based on the value of visible? I don't see any functions to set visibility at http://racerender.com/RR3/docs/DispObjEnhanced.html

    I just meant to double-check that your variable "Visible" is actually tied to the output that you are monitoring. There is no provisions for controlling the display object's visibility from within the script, other than your ability to make the script not execute any drawing functions, of course.

    To make matters worse, RaceRender is crashing repeatedly when there are compile errors in the script (typos essentially), I'm using the 20170824 build (3.6).
    Do you have an example so that I could replicate the crashing here? I haven't been able to get this to happen to me yet.

    Quote Originally Posted by leisurehound View Post
    hmm...have it sort of working with this in the foreground script:

    if(Datavalue > 0) { //no short circuit evaluation using &&, causes divide by zero e.g. if(DataValue>0 && strobe(60/DataValue)
    Visible = strobe(60/DataValue);
    }

    if(Visible) {
    DrawDot(CenterX, CenterY, MainColor, Space / 2);
    } else {
    DrawDot(CenterX, CenterY, BackColor, Space / 2);
    }

    But it looks like Strobe() doesn't like a parameter that varies in time; it appears to get confused on whether it should be 1 or 0 once the input parameter changes.

    Here's a sample video where the strobe does no really reflect the frequency of the input signal
    https://www.youtube.com/watch?v=Z7yB...ature=youtu.be

    Thoughts? (other than calculating my own period counter to track visibility)
    That is an odd effect, but I suppose it makes sense... Strobe() is simply dividing the current sample time by the given interval, rounding the result to an integer, and then returning true if that is an odd number or false if even. Works good for most stuff, but if the interval is changing every time, then it would be effectively redefining what's odd or even. That is then combined with the effect of being rendered at a video frame rate that may not align to the flashing interval very well, which could cause some flashes to appear too short, too long, or even have some get combined or skipped entirely. The preview screen wont be very accurate for showing this, as its actual frame rate can be variable based on system performance, so you'll get much more consistent performance out of your actual output video. Setting your output video's frame rate to 60 FPS may also help you here.

    Quote Originally Posted by leisurehound View Post
    Trying to implement my own logic to change the color on my own at varying intervals based on the HR data. The logic is pretty simple, calculate a duration based on the new data value, then see from the last toggle time to now is longer than the duration, and if so toggle the light state & update last toggle time. Using the print function seems to re-initialize everything when opening the editor so its hard to debug. Is there a way to advance frames from within the script editor and have the script re-evaluated and display the printed values? Running it outside the editor seems to toggle light state on first execution and then never toggles it back the next time the toggle duration is exceeded.

    SinceLastToggle = SampleTime - LastToggleTime;

    print (SampleTime, LastToggleTime, SinceLastToggle, ToggleDuration, LightState);

    if (DataValue != 0) {
    ToggleDuration = 60 / DataValue;
    }

    if (SinceLastToggle > ToggleDuration) {
    LastToggleTime = SampleTime;
    LightState = !LightState;
    }

    print (SampleTime, LastToggleTime, SinceLastToggle, ToggleDuration, LightState);

    if(LightState) {
    DrawDot(CenterX, CenterY, MainColor, Space / 2);
    } else {
    DrawDot(CenterX, CenterY, BackColor, Space / 2);
    }

    I haven't tested your exact code, but this approach should be possible, if you go to the "Object Parameters" tab and enable "Persistent Script Variables". That will enable your "SinceLastToggle" variable to stay alive, rather than being destroyed after each video frame render.

    Quote Originally Posted by leisurehound View Post
    Also, is there any means to display an PNG as an object?
    Yes. To add a PNG or other image as a display object, you could use "File" -> "Add Embedded Image to Project..." and then select the file. That will add it as an Embedded Image object (ie an "E Image"), and its data will be contained within your RaceRender project, rather than being linked to the input image file on your system (as it would be if you added it as a normal input file). You can also make it appear in your E Image menu by double-clicking on it to open its properties box on the right, clicking the "Export" button, and then saving it into your Documents -> RaceRender 3 -> Images folder.

  9. #9
    Tuner in Training
    Join Date
    May 2015
    Posts
    28
    Thanks Weston, these tips are helpful.

    I've added the image, but are users not able to create enhanced objects on their own and/or instead use a DrawImage() method to show and hide the image? Or do I need to draw and fill the shape I'm interested in by adding lines, dots & circles?

  10. #10
    Tuner in Training
    Join Date
    May 2015
    Posts
    28
    I think I found how to export enhanced objects, using an existing one to create a new one but not create a new one from scratch.

    Am still having trouble getting the light state to change at a variable interval. I believe I have the logic correct but the color is being toggled on each frame when going frame by frame in preview pane, which is not correct. When I create a video it is flashing much more often than necessary, but unclear if its every frame or not. It definitely seems like things are getting clobbered between frame renders. Here's the code:
    //Background

    LastToggleTime = 0
    LightState = false
    ToggleDuration = 999.99

    //Foreground
    if (DataValue != 0) {
    ToggleDuration = 60.0 / DataValue;
    }

    SinceLastToggle = SampleTime - LastToggleTime;

    if (SinceLastToggle > ToggleDuration) {
    LastToggleTime = SampleTime;
    LightState = !LightState;
    }

    if(LightState) {
    displayColor = MainColor
    } else {
    displayColor = BackColor
    }


    Just to confirm the logic, I created a Swift function and ran it in Xcode playgrounds. This toggles the light state as expected. Is it possible to see what the code generated by your parser to see what is happening? Here's the same logic implemented in Swift which works as expected:

    var lastToggleTime = 0.0;
    var lightState = false
    var toggleDuration = 999.99


    func toggleLight (sampleTime: Double, dataValue: Int32) {

    print("Sample Time: ", sampleTime, "DataValue: ", dataValue)
    if dataValue != 0 {
    toggleDuration = 60.0 / Double(dataValue)

    }

    print("Toggle Duration: ", toggleDuration)

    if sampleTime - lastToggleTime >= toggleDuration {
    lastToggleTime = sampleTime
    lightState = !lightState
    }

    print("LightState: ", lightState)
    print("\n")

    }

    var i = 0
    while (i < 25) {
    toggleLight(sampleTime: Double(i)*0.1, dataValue: 60)
    i += 1
    }


    And the Swift output:

    Sample Time: 0.0 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 0.1 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 0.2 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 0.3 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 0.4 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 0.5 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 0.6 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 0.7 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 0.8 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 0.9 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 1.0 DataValue: 60
    Toggle Duration: 1.0
    LightState: true


    Sample Time: 1.1 DataValue: 60
    Toggle Duration: 1.0
    LightState: true


    Sample Time: 1.2 DataValue: 60
    Toggle Duration: 1.0
    LightState: true


    Sample Time: 1.3 DataValue: 60
    Toggle Duration: 1.0
    LightState: true


    Sample Time: 1.4 DataValue: 60
    Toggle Duration: 1.0
    LightState: true


    Sample Time: 1.5 DataValue: 60
    Toggle Duration: 1.0
    LightState: true


    Sample Time: 1.6 DataValue: 60
    Toggle Duration: 1.0
    LightState: true


    Sample Time: 1.7 DataValue: 60
    Toggle Duration: 1.0
    LightState: true


    Sample Time: 1.8 DataValue: 60
    Toggle Duration: 1.0
    LightState: true


    Sample Time: 1.9 DataValue: 60
    Toggle Duration: 1.0
    LightState: true


    Sample Time: 2.0 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 2.1 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 2.2 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 2.3 DataValue: 60
    Toggle Duration: 1.0
    LightState: false


    Sample Time: 2.4 DataValue: 60
    Toggle Duration: 1.0
    LightState: false

  11. #11
    Tuner in Training
    Join Date
    May 2015
    Posts
    28
    Any interest in sharing the codegen here Weston? Am happy to help debug.