Award
Congratulations Rich, for answering the question and has received an EZ-Credit award! Share what you have learned and create a tutorial to help others by clicking here.

Trying To Do A Video Recording

Assistance Requested

Help bhouston with their question and receive $10 of EZ-Credit to get more robots and parts from our store. The following information was provided about their previous efforts searching tutorials for a resolution.

bhouston claims to have checked these sources:
 
#1

Not having any luck with this script! The head isn't turning as it should. The Camera Control indicates that it is recording, however, I can't find the recording where it says it should be. Any help appreciated. Thanks

Code:


#start head in this position
servo(D1,110)
servospeed(D1,0)
sleep(500)
#start video recording
ControlCommand("Camera", CameraRecordStart)

sleep(50)
#head should move to the left in increments of 10 degrees
ServoUP(D1,10)
servospeed(D1,2)
sleep(5000)
$x=Getservo(D1)
sleep(500)
#when the head gets to 150 degrees it should move to the right
if($x > 150)
servoDown(D1,10)
servospeed(D1,2)
sleep(5000)
#when the head gets to 50 degrees it should go back to starting position
elseif($x < 50)
servo(D1,110)
endif
#stop video recording
ControlCommand("Camera", CameraRecordStop)
Stop()

I have found a few conversations, tutorials and activities that may help with your question. Take a look at these links. I've sorted them by what I believe to be most relevant but that is not always the case as I'm still learning.


Also, consider reviewing the Learn section for informative lessons and activities. Check it out!


#2

Not your script. There is an open bug report

http://www.ez-robot.com/Community/Forum/Thread?threadId=7245

Video recording has been broken for a while.

Alan

#3

Ok, thanks. That explains that problem. Any idea why the servo down and servo up isn't working?

#4

Your script doesn't have any loops around the IF which checks the position of the servo, it moves the servo UP 10 degrees and checks for it's position but doesn't move the servo again unless it's at > 150 or < 50.

Since it starts at 110 and moves up by 10, so to 120, it doesn't match either > 150 or < 50 so will only move to 110 then up by 10 degrees before the script stops.

Add a repeat or loop in around where it's checking and moving the servo up/down by increments.

#5

Thanks Rich. That made sense. I've got it working now, here's what I came up with;

Code:


#start head in this position
servo(D1,110)
servospeed(D1,0)
sleep(500)
#start video recording
ControlCommand("Camera", CameraRecordStart)
:start
sleep(50)
#head moves to the left in increments of 10 degrees
ServoUP(D1,10)
servospeed(D1,2)
sleep(500)
$x=Getservo(D1)
#sleep(50)
#when the head gets to 150 degrees it moves to the right
if($x > 150)
Goto(step2)
else
Goto(start)
:step2
endif
servoDown(D1,10)
servospeed(D1,2)
$x=Getservo(D1)
sleep(500)
#when the head gets to 50 degrees it goes back to starting position
if($x < 70)
servo(D1,110)
else
Goto(step2)
endif
#stop video recording
ControlCommand("Camera", CameraRecordStop)


Hopefully, the video recording bug will be fixed soon. (hint, hint, wink, wink, DJ ) I'm planning to use this as part of a security system for my house. For now I'll have it take snapshots.

#6

If it works that's great, however in the interests of giving more information for a wider audience and covering the many methods, I would have written it like this;

Code:


#start head in this position
servo(D1,110)
servospeed(D1,0)
sleep(500)

#start video recording
ControlCommand("Camera", CameraRecordStart)
sleep(50)

$x=Getservo(D1)
RepeatUntil($x = 150)
#head moves to the left in increments of 10 degrees
ServoUP(D1,10)
servospeed(D1,2)
$x=Getservo(D1)
sleep(500)
EndRepeatUntil

#when the head gets to 150 degrees it moves to the right
RepeatUntil($x = 50)
servoDown(D1,10)
servospeed(D1,2)
$x=Getservo(D1)
sleep(500)
EndRepeatUntil

#when the head gets to 50 degrees it goes back to starting position
servo(D1,110)

#stop video recording
ControlCommand("Camera", CameraRecordStop)



Neither way is wrong nor is either better, just a different solution to the same problem Smile

Note: My code wasn't written in EZ-Builder and is unchecked therefore there may be some slight syntax errors.

#7

That's a cool thing about EZ-Builder - there are different ways to write a script to achieve the same thing. Here's another way using Auto Positions and ControlCommand()s;

Code:


ControlCommand("Auto Position", AutoPositionFrameJump, "Rest")
sleep(500)
ControlCommand("Camera", CameraSnapshot)
sleep(500)
ControlCommand("Auto Position", AutoPositionFrame, "Head Right",25,3,4)
sleep(3000)
ControlCommand("Camera", CameraSnapshot)
sleep(500)
ControlCommand("Auto Position", AutoPositionFrame, "Head Left", 25,3,4)
sleep(3000)
ControlCommand("Camera", CameraSnapshot)
sleep(500)
ControlCommand("Auto Position", AutoPositionFrame, "Rest", 25,3,4)


When the video recording is up and running I'll replace the "Camera Snapshot" with the "Camera Record" CC.

#8

I was looking at the code used in scripts, and not just this one. All the ones I have seen tend to do things the same way. But this code brings up one of the things I have seen often. That is, using sleep delays as the way of giving the servo time to do it's movement. This just seems too imprecise to me. Maybe I'm just being picky (I am a long time programmer (Modula2, ADA, Delphi) and tend to see things in a highly structured and precise way. Anyhow, I'm referring to this section:

Code:


$x=Getservo(D1)
RepeatUntil($x = 150)
#head moves to the left in increments of 10 degrees
ServoUP(D1,10)
servospeed(D1,2)
$x=Getservo(D1)
sleep(500)
EndRepeatUntil



As I see it, the statement sleep(500) is there to give the servo time to move to
the new position and keep the system from checking the servo position hundreds (thousands?) of times needlessly. Thing is, how long it takes to get there is entirely predicated on the ServoSpeed set. Unless calculated, the sleep time would be a guess or fudge factor at best. Also the servo is going to be commanded to move another 10 degrees from it's current position regardless of whether the servo has made it to the last place it was commanded to go at that moment.

Instead, I was wondering if it might be better to do something like this:

Code:


$CurrPos =Getservo(D1)
$PrevPos =$CurrPos
RepeatUntil($CurrPos >=150)
#head moves to the left in increments of 10 degrees
ServoUP(D1,10)
ServoSpeed(D1,2)
#Now, wait for the head get into position
RepeatUntil($CurrPos >=$PrevPos+10)
$CurrPos =Getservo(D1)
Sleep(100)
EndRepeatUntil
$PrevPos=Getservo(D1)
EndRepeatUntil


Darn code brackets! Takes out all my lovely formatting.

Here the sleep statement is there only to prevent needless checking of the servo position. In this case limiting it to 10 times a second. There is also the issue of getting out of the loop in case of failure, as well as, favoring RepeatWhile over RepeatUntil but those are other topics. No sense in clouding the issue with that here.

Please let me know of any flaws in my thinking, thanks.

BTW, To whom it may concern ... there is a mistake in the Script manual concerning the RepeatWhile statement definition. The example shows a RepeatUntil statement instead of RepeatWhile. Also both commands show EndRepeat in both instead of EndRepeatUntil and EndRepeatWhile. EndRepeat may be valid for either, but the definition says to use EndRepeatUntil or EndRepeatWhile. Consistency may be the hobgoblin of little minds, but in programming it's a virtue. Smile (yeah I know, the quote is Foolish Consistency, just go with me here)

#9

On my phone so going to be brief and only touch on one thing. The sleep is not for waiting for the servo but to help reduce the demand on resources.

Also, the servo position is not read from the servo but from the software. Repeating until a variable or command which reads the servo position meets the specified position is redundant since, as far as EZ-Builder (and any other software) is concerned, it's already at that position the instance you send the Servo() command.

#10

Wbs, those old languages with a single threaded approach is what makes relearning coding today difficult. The approach you wrote is incredibly inefficient and very expensive on processor and network resources.

First, you only need to assign a servo speed once, not looping.

Second, the threaded approach is to set the speed and servo position once and let the processing be offloaded onto the ezb and servo. Releasing cpu cycles for other threaded tasks.

The auto position is a good tool to begin using. Specifically for poses.

For the last 10-15 years, cpu processing has been approaching speed limitations. The approach of using multiple cores has become what the operating system and newer programming languages rely on. At the heart of the kernel (in any current OS) is a layer which distributes instructions across multiple cores and creates a threading interface for the OS and programs. There are a few different approaches during programming for using threads which evolve with compilers and libraries.

EZ-Builder and other robot software/libraries (such as ROS) use a an approach which run processes separately as jobs. Each "job" in EZ-Builder is a control. They run parallel and communicate using ControlCommands().

While you can surely hack EZ-Script (or any current language) to write old school code, it's not going to always work as expected once you start adding additional processes (controls).

For example, the correct approach for you script to simply move a servo to a pose would be to create Auto Position poses and execute them with the ControlCommand(), accessible from the Cheat Sheet (see the learn section and the Activities course) for information on how it works.

If you were to do something like this...

Code:


ServoSpeed(d2, 4)
Servo(d2, 120)



Soon as you execute the Servo() command, it is non-blocking (as all commands in EZ-Script are non-blocking unless stated with the word WAIT). This means the Servo() command will instruct the EZ-B to begin moving the servo to position 120. The servo is a WRITE only device, meaning it doesn't report back the position of itself. It only moves when told - so there is no way to know it has moved unless you use the Auto Position. The Auto Position is a very very easy control with very very very very complicated code in the backend. It will report when an action has been completed executing, which you can monitor by using the following command after initiating a ControlCommand() on an Auto Position Action.

Code:


WaitUntil( $AutoPositionStatus = 0)



For more information on the dozens and dozens of Example Projects demonstrating EZ-Script, check the EXAMPLES in EZ-Builder. There is an entire lesson in the learn section located under Activities regarding the Examples in EZ-Builder.