I remember DJ commenting a few weeks ago that using the waitforchange command takes just a little bit more resources then a loop using a GoTo command. It seems that most proficient script writers here are under the impression that it's the other way around. I thought so too until I read DJ's comment. Did I misunderstand what DJ was saying and the waitforchange command is really most efficient way to go?
Also; if the waitforchange is truly a loop that runs in the background and constantly checks status of the $variable do we need to insert a Sleep command like a GoTo loop to help with freeing up resources?
Any thoughts or answers? Thanks!
Asked
— Edited
There is a limited bandwidth to the EZ-B over wifi and the EZ-B has a processor that is many time smaller than the one in your computer. It is easy for your computer to overpower this processor. That being said, the way I use the WaitForChange is that I first think about where the resources are going to be consumed. I dont use a WaitForChange when querying an ADC port for example. I would rather control how quickly the commands are being sent so as to prevent lag with other components. I use a loop with a sleep command to limit this. If the processing is taking place on the computer, for example between roborealm and ARC, I use a waitforchange without much concern for how many resources are being consumed. The PC has multiple processor cores and can easily handle something running in the background without much concern.
I hope first that I understand things correctly and then I hope that I offered an explanation of "depends on the usage".
Using wait for change in just a variable is great and very effecient.
Could you give me an example of using wait for change so I can try to understand that concept better?
http://www.ez-robot.com/Community/Forum/Thread?threadId=7667&page=3
This is two applications on the PC communicating with each other over TCP port 6666. There is really no latency here and no real network traffic. This is querying a variable in ARC for a change and not jumping over to the EZ-B for anything.
Something like
Code:
This would be bad. This is where you would want to use another loop instead of the waitforchange because the wait for change has no built in delays. It should look more like this
Code:
The second would query the port on the EZ-B every second instead of multiple times a second.
**This code is untested and is simply for demonstration purposes.
So the code would be having the Wait For Change command just watch a stated Variable in ARC for change. This command would have to be in a loop with an If statement that would trigger an action when the variable changes.
The real difference is where is the processing taking place. If I am just looking for a variable change in ARC, the WaitForChange is great. If I am querying a port on the EZ-B, the waitforchange command isn't so great. The reason is that there is no delay in the command. it will run say 1000 times a second (just an estimate). If I query a port on the EZ-B that many times, what do I gain? What do I loose? The gain would be nothing and the lose would be performance from anything else on the V4. It would saturate or flood the Wifi connection with useless traffic.
If I determined that I want to have this port queried every second as that is fast enough, I would have to insert a delay in the loop. you cant do that with the WaitForChange command, but with a loop and sleep command it can be done. The sleep prevents the wifi connection from becoming saturated to the point that your other ports can't respond to the queries being asked of them.
This isn't an issue with looking at a variable for it to change in ARC. It is within its own application on its own machine with no network latency. It is just hitting memory on your computer which is very fast. Network and especially wifi is the slowest part of the chain. It really depends on where the processing is happening as to what the best use is. As a rule, I would say that if you are querying something on the EZ-B (digital, analog, I2C, Serial, Temp, Voltage...) I would use the loop method. If your doing something within ARC that isn't specific to the hardware on the EZ-B, you should use the WaitForChange.
Man this is a great place to learn how to become a robot genius...
Richard
I also think you helped me wrap my head around what was happening in ARC (along with others here). Understanding is key with scripting and with pretty much everything that we do here. Fear to learn is the thing that keeps most people back. This community doesn't have that fear which makes it a very powerful community.
For instance, the digital clock I wrote for the LCD display in Melvin used WaitForChange to check the time and update every second but I could have written more code and used an If and Goto loop.
The good code was (simplified to print rather than I2C commands);
Code:
The same result could be done by checking the seconds using an IF statement and looping until the seconds changed (I won't post the code since it's pointless).
Similar is the RepeatUntil command, this can also be achieved by using an IF statement however it's pointless and more code if you do use an IF statement to loop so many times. If I can save on writing 1 extra line of code I will.
I ask because I had envisioned that the V4 was running a process "in the background" (a thread), looking at a variable on board itself and returned a point of data when the variable changes, placing it in a variable in the PCs memory.
This allows the pc to be used for all of the heavy lifting. The ezb is basically a communication bus. This is why DJ described EZROBOT as a software company. It also allows updates to be made without having to update the EZB. It is also why ARC can run without being connected to the ezb.
I wonder, do instructions such as GetPWM() come from the ARC PC memory (simply the last value to which it was set via PWM() from ARC), or do they come from the ezb itself? It seems like the ezb would need to store such values somewhere to refer to each time it moves the servo. Same for GetServoSpeed().
Don't quite get things like WaitForChange(GetServo(d0)) - an example in the Script Manual. Since you can't read the position of the servo from the ezb, that would mean all you are doing is reading the last set value of some global variable in ARC. It will only change when another servo instruction of some form is sent. Thing is there will be no instructions sent until there is a change. So it's seems to be a catch-22. The script would never move on.
This particular WaitForChange(GetServo(d0)) example you gave might be useful if you have one script controlling another without actually having to reference that script directly or even by name... Here's an example.... say you had a main controlling script that moves servos for your robot.... You then created a second script that runs continuously in the background waiting for servo movement changes before executing. When your main script tells a servo to change positions this will trigger WaitForChange(GetServo(d0)) in your background script to run.... As mentioned you can't actually read servo positions directly but you can read referenced movement changes within ARC....
Remember think "multitasking" when you think of the way the ez robot software and ezb work.... This is one of the main reasons ez robot so much more powerful than other robotic platforms.... As David mentioned it is all about the software.... If fact if anything it is the ezb4 that is the weak link in the chain here... I am not saying there is anything wrong with the ezb4 as it still is the best robot controller in the world, but it holds back ARC in a sense.... This is because the software is so outstanding... If DJ sold his entire inventory and circuit design for the ezb4 he would make thousands.... If he sold his software he would make multi millions.... Anyway, you will get that eureka moment soon enough, trust me...
Thank you for your explanation. Yes, it makes sense when you are running multiple scripts simultaneously. One waiting for the other to move the servo.
The ezb does seem to hold back ARC in a sense, as you say, by not taking on more of the processing chores. After all, ARC could, it seems to me, cause a thread to be spawned in ezb (which runs in ezb) that waits for the servo to change and then sends data to ARC when it does. No script looping required, and no danger of overloading the communications link. I suppose though, that would go against the philosophy of the ezb being only a controller and the ARC program doing all the higher lever brain work, including keeping track of where the servos are supposed to be. There would have to be closer coupling between the ezb and ARC in both directions then as well. To run without a robot, there would have to be a "Simulator Mode" built into ARC. A level of abstraction not needed with the current software model. ARC can run without the robot, but the robot cannot run without ARC.
Still, it would be fun to try to run your own side programs in the ezb, but we don't know enough about the architecture of the ezb as a whole to readily do that.