Australia
Asked — Edited
Resolved Resolved by DJ Sures!

How To Write A Code To Save The Servo Data As Text With Timestamps?

Hi I am trying to write a code for JD Humanoid where I can track the data coming from the servo. First I tried to write the following ode with EZ-Script. It serves my initial purpose but I also need a proper timestamp in "ddmmyyyyhhmmssffff" format. Apparently it seems that I can't do it with EZ-Script. So, I am thinking to write a similar code in Python as I can make the required timestamp formatting there. So, can anyone help me with this? Thanks.

ControlCommand("Graphy", RemoveAllSeries)

:loop

$pos0 = getservo(d0)
ControlCommand("Graphy", AddData, "Servo D0", $pos0)

$pos1 = getservo(d1)
ControlCommand("Graphy", AddData, "Servo D1", $pos1)

controlCommand("Camera", "CameraMovementTrackEnable")
ControlCommand("Graphy", AddData, "Servo D4", $pos)

FileWriteLine("c:\temp\mylog.txt", $time + ", servo D0: " + $pos0 + ", servo D1: " + $pos1)

sleep(10)

goto(loop)


Related Hardware JD Humanoid
Related Control Graphy

ARC Pro

Upgrade to ARC Pro

Unlock the true power of automation and robotics by becoming a proud subscriber of Synthiam ARC Pro.

PRO
Synthiam
#1   — Edited
  1. Is there a reason for setting the movement tracking enabled for the camera every 10 ms in the loop? Or is it an accident? Because that's like bashing the mouse button on the option over and over and over and over and over. It'll use up a ton of cpu and slow down your computer. You only need to set it once. Set it outside the loop at the beginning of the program - just like you do when clearing the graph.

  2. ez-script will only give you a second resolution. You can do it with this, but you only get 1 second resolution from the date object. It's documented in the ezscript manual when editing ezscript.

User-inserted image


$datestamp = $day +":"+ $month +":"+ $year +":"+ $hour +":"+ $minute +":"+ $second

print($datestamp)

  1. JavaScript is fastest and easiest. I'd recommend JavaScript way before python. There's lots of great javascript manuals. The one synthiam recommends that is documented in the javascript manual is here: https://www.w3schools.com/jsref/jsref_getday.asp

var x = new Date();

print( x.getDay() );

  1. Is there a reason the date format absolutely needs to be ddmmyyyyhhmmssffff? Because you will have to use extra processing to ensure padding on single digit numbers (i.e. 5 must become 05). It would be ideal to separate each date value with a : like how clocks and such do. So it would be dd:mm:yyyy:hh:mm:ss:ffff   OR just use a space between each one like other date parsers do. So it would be dd mm yyyy hh mm ss ffff

  2. I'm sure JavaScript has a ToString() that might accept a formatting specification. So you can output the exact format you desire. I imagine it would be documented in the JavaScript manual from the link above

  3. It appears Graphy has a SAVE TO CSV option as well...

    User-inserted image

PRO
Synthiam
#2   — Edited

Oh - one more thing... a 10ms loop is considerably fast. Have you considered calculating an optimized loop delay? Or even keeping the last state of the previous servo positions in an array and only writing if a servo has actually changed position?

Something like... (ps, line 30 should use File.appendStringLine)

User-inserted image

Australia
#3  

Thank you very much DJ Sures for your prompt response. I was not very sure about the delay but I needed it the range of a few milliseconds. So, I guess around 100 ms will also work for me. I'll try that. Also, thank you for pointing me to JavaScript as it has better documentation. I mainly need the hh:mm:ss:ffff type for saving the timestamps, because I want to observe the histogram of the inter-arrival times. This is why it is problematic so save directly as a CSV file from Graphy cannot log the timestamps.

PRO
Synthiam
#4  

Okay - tomorrow the web dev is going to fix the bug with posting code. That means I can repost that code with some improvements - specifically a sleep() in my loop would be useful. I accidentally left that out.

the code is a pasted image because of the web forum bug. Once it’s fixed I can repost  the code for you to copy and paste

Australia
#5  

Oh I see.. that's really good news. Thanks a lot. Much appreciated for your help. Cheers!

Australia
#6  

With a slight modification to fix the single digit issue in printing timestamps. Thanks.

var filename = "c:\\temp\\mylog.txt";
var servos = [d0, d1, d4];
var lastPositions = [-1,1,-1];

function addZero(x,n){
  while(x.toString().length < n){
    x = "0"+x;
  }
  return x;
}

while(true){
  var requiresUpdate = false;
  for(var i = 0; i < servos.length; i++){
    var p = Servo.getPosition(servos[i]);
    if(p != lastPositions[i]){
      lastPositions[i] = p;
      requiresUpdate = true;
    }
  }
  
  if(requiresUpdate){
    var d = new Date();
    var outStr = addZero(d.getHours(),2) + ":" + addZero(d.getMinutes(),2) + ":"+ addZero(d.getSeconds(),2) + ":" + addZero(d.getMilliseconds(),3);
    
    for(var i = 0; i < servos.length; i++)
      outStr += "," + lastPositions[i];
      
    File.appendStringLine(filename,outStr);
  }
}
PRO
Synthiam
#7  

you'll benefit with a sleep(10) in there to be friendly on the cpu thread of the script

PRO
Synthiam
#8  

Here you go - this is a good script that will run faster than calling a user defined method every time for padding. There's only two things necessary to modify in this script.

  1. Filename
  2. Servos

// Add the filename and use double \\ for the folder separator
var filename = "c:\\temp\\mylog.txt";

// add the comma separated list of servo ports to record
var servos = [d0, d1, d4];

// used for the last position of servos to know when to write to file
var lastPositions = new Array(servos.length);

while(true){
 
  var requiresUpdate = false;
  
  for(var i = 0; i < servos.length; i++) {
  
    var p = Servo.getPosition(servos[i]);

    if (p != lastPositions[i]) {
    
      lastPositions[i] = p;
      requiresUpdate = true;
    }
  }
  
  if (requiresUpdate) {
  
    var d = new Date();
    var outStr = d.getHours().toString().padStart(2, '0') + ":" + 
                 d.getMinutes().toString().padStart(2, '0') + ":"+ 
                 d.getSeconds().toString().padStart(2, '0') + ":" + 
                 d.getMilliseconds().toString().padStart(2, '0');
    
    for(var i = 0; i < servos.length; i++)
      outStr += "," + lastPositions[i];
      
    File.appendStringLine(filename,outStr);
  }
  
  // be easy on the cpu
  sleep(10);
}

Australia
#9  

Thanks a lot. Now I can extract the data just as I wanted!