Singapore
Asked — Edited

Help Prevent Jf Faceplanting

Hi all,

When my JD decides that his battery level is low, he lurches forward from a standing position and does a spectacular faceplant on my desk or floor!

To prevent the poor guy cracking his face, I was hoping to script an early warning system that would advise me when he was approaching critical level so I could at least lay him down flat first.

If I recall correctly, the battery warning cuts in at around 6.6 volts so I wrote this small code snippet which runs after connection to alert me when the voltage dipped below 7 volts.


:loop
$batteryLevel=GetVoltage() 
if ($batteryLevel < 7)
ControlCommand("Soundboard v4", Track_12) 
endif 
sleep( 60000 )
Goto (loop)

Track 12 is an audio file that advises 'Energy Cell Exhausted' (I know many of you will guess where that came from:) ).

Whilst the script works, it is not reliably firing off before JD complains his battery level is low and does his faceplant thing.

Can anyone suggest a better method of achieving an early warning alert?

Thanks.


ARC Pro

Upgrade to ARC Pro

Synthiam ARC Pro is a new tool that will help unleash your creativity with programming robots in just seconds!

Singapore
#1  

It seems I can't edit the title of my post (should of course read 'JD' not 'JF') ... sorry about that!

#3  

The low battery level warning releases the servos if I recall correctly. This is why he falls.

The reason your script is inaccurate is because, based on the situation, the servos moving can drag the battery voltage down fast. Because of this, you need to monitor the voltage more rapidly. I would recommend between 5000 and 10000 milliseconds. This should catch him before the low battery warning.

I would also suggest you experiment with adding a command to stop the currently playing action, and go to a sitting position. This may not always work and will get him off balance, but it is an idea.

PRO
Synthiam
#4  

The battery monitor in the ezb isn't a simple "if voltage is less than x". There is an algorithm that monitors the voltage over time and trends the value. This is because the voltage can dip from load, doesn't necessarily mean the battery requires charging.

The battery monitor uses a custom complimentary filter to remove false positives. You could write that all as en ezscript, but the sample rate would require a great deal of bandwidth to reproduce the functionality. A complimentary filter with a lengthy delay will not be effective. However you could at least check the voltage 3-4 consecutive times before assuming the voltage is low.

#5  

So... Of course, this leads to a feature request for some future firmware... Could we get two levels of battery alert. The first a less irritating one time alert that the battery is low, and a second more urgent alert when it is lower that also releases the servos and goes into low power mode so if the robot is accidentally unattended it might not permanently kill the battery.

Alan

Singapore
#6  

Thanks @DJSures & @MazeHorizonTech,

The following modified code seems to work relatively well, and I have followed both of your suggestions. Now JD samples the voltage every 10 seconds, and averages the voltage over the last 3 samples. When he detects the average voltage has dropped below 7.05 volts, he announces a warning, stops any action he is doing and sits down (provided he is not already sitting). Whilst the voltage remains below the threshhold he will repeat his warning message every 30 seconds (10 seconds was wayyy too frequent).

This seems to give sufficient time for an early warning before the EZ-B battery saver kicks in at around 6.98 volts. That being said, I am still tinkering with the threshhold to ensure he's not complaining too early, but still prrior to faceplant-time.

I've included the code below in case it is of benefit to anyone else, although it is still a fairly basic script. I have commented the code extensively to help anyone new to scripting to utilise it.


#Initialise Variables
clearVariable(&quot;$voltageHistory&quot;)
DefineArray($voltageHistory,3,7.05)
$batteryLoopCount=0
$batteryAnnouncement=0

#Execute Main Loop
:loop

#Populate Voltage into Array
$voltageHistory[$batteryLoopCount]=GetVoltage() 
$batteryLoopCount++
if ($batteryLoopCount &gt; (getArraySize(&quot;$voltageHistory&quot;)-1))
  $batteryLoopCount = 0
endif

#calculate Average Voltage
$batteryLevel = 0
repeat($x,0,getArraySize(&quot;$voltageHistory&quot;)-1,1)
  $batteryLevel= $batteryLevel + $voltageHistory[$x]
endrepeat 
$batteryLevel = $batteryLevel / getArraySize(&quot;$voltageHistory&quot;)

#If average voltage &lt; 7.05 volts, play sound, stop current action and sit down
if ($batteryLevel &lt; 7.05)
  #Don't announce every time, once every 30 seconds is annoying enough
  if ($batteryAnnouncement=0)
    ControlCommand(&quot;Soundboard v4&quot;, Track_12)
    $batteryAnnouncement++
  else
    $batteryAnnouncement++
  endif
  if($batteryAnnouncement&gt;2)
    $batteryAnnouncement=0
  endif 
  #no need to sit if already sitting:)
  if ($AutoPositionAction != &quot;Sit Down&quot;)
    ControlCommand(&quot;Auto Position&quot;, AutoPositionAction, &quot;Stop&quot;)
    sleep(3000)
    ControlCommand(&quot;Auto Position&quot;, AutoPositionAction, &quot;Sit Down&quot;)
  endif
else
  # if average battery level &gt; 7.05 volts, reset the 
  # announcement counter so that JD will speak the next time
  # the voltage drops
  $batteryAnnouncement=0
endif

#Sleep for 10 seconds and return to start of loop
sleep( 10000 )
Goto (loop)

PRO
Synthiam
#7  

That looks like it should work in conjunction with the built in battery monitor

#8  

Thanks @Aceboss. DJ, I rescind my feature request. This seems like it should do the job.

Alan