Recently, I had a problem with my BittleX robot and, after reporting it here, it was diagnosed as having a power circuit failure. I then requested a replacement from support, and they sent the replacement board. (Many thanks go to the Petoi team, from top-to-bottom, for their efforts towards getting me the new board.)
Replacement Biboard installation
The installation of the board was mostly uneventful with one, minor exception. The Ultrasonic sensor that sticks out at the front of the board is unadjusted and may interfere with the movement of the robot head. You should bend the sensors downward towards the shoulder in order to prevent interfering with the head. You can test the head clearance with all power off.
Mysterious Behavior
With the Biboard installed I ran my diagnostic software with terrible results; the bot moved in a chaotic manner, with many collisions between legs and body. I kept reducing the tests performed until I was able to isolate a single test that demonstrates some mysterious behavior previously unknown to me.
The first video (https://youtu.be/EmBHQHdSwBM) shows the mysterious behavior (n.b., the test is run twice for clarity). The same test is performed for each servo, HEAD, RLEG, LLEG, in that order. The test places the bot into a pose that is suitable for performing the test without interference. This is done before and after the actual test to provide a visual cue the test has completed. When the test completes the test framework resets the pose to the "zero" pose.
The test itself is fairly simple. First the servo is set to the maximum angle (120 degrees for the head servo; 90 for all others). When that command completes the servo angle is read and compared to the expected angle. The smaller of the two is declared the maximum value. For the minimum angle the value is -120/-90 digress and the maximum result is used as the minimum angle for the servo.
The mysterious behavior is that the LLEG does not return to the test pose after the minimum angle test. Note that for all other servos the move is performed.
So what is the reported position of the LLEG (servo 15)?
The test pose command sent is verified by reading the servo positions. We can see this in the log. First, the -90 position is set
ftBittleX::ftfBittleX::on_send
TX command : m15 -90
write count : 8
expected : 8
actual : 8
ftBittleX::ftfBittleX::on_response
Command completed: normal
description : INDEXED_SEQUENTIAL_ASC
cmd : m
id : 12
data : 15 -90
1747 ms : RX_latency
0 ms : RX_elapsed
response : 1 lines
m
response : end
Then the position is checked
ftBittleX::ftfBittleX::on_send
TX command : j15
write count : 4
expected : 4
actual : 4
ftBittleX::ftfBittleX::on_response
Command completed: normal
description : Joints
cmd : j
id : 8
data : 15
3 ms : RX_latency
1 ms : RX_elapsed
response : 3 lines
=
-80
j
response : end
ANGLE MISMATCH: -90 != -80
The failure is the purpose of the test.
The test pose is then reset
ftBittleX::ftfBittleX::on_send
TX command : i0 0 12 90 8 0 13 90 9 0 15 90 11 45 14 90 10 45
write count : 49
expected : 49
actual : 49
ftBittleX::ftfBittleX::on_response
Command completed: normal
description : INDEXED_SIMULTANEOUS_ASC
cmd : i
id : 6
data : 0 0 12 90 8 0 13 90 9 0 15 90 11 45 14 90 10 45
692 ms : RX_latency
1 ms : RX_elapsed
response : 1 lines
i
response : end
The pose is verified
ftBittleX::ftfBittleX::on_verify
ftBittleX::ftfBittleX::on_send
TX command : j
write count : 2
expected : 2
actual : 2
ftBittleX::ftfBittleX::on_response
Command completed: normal
description : JOINTS
cmd : j
id : 8
5 ms : RX_latency
9 ms : RX_elapsed
response : 4 lines
=
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0, 0, -49, -4, 0, 0, 0, 0, 0, 0, 45, 45, 90, 90, 90, 90,
j
response : end
ftBittleX::ftfBittleX::on_verify: joint list match
Disturbia.
The physical state does not match the reported state.
The result of this is that when the test framework tries to move to the "zero" pose, the LLEG is in a collision condition with the body and the movement "slides" the leg along the body until it suddenly moves properly. I have to conclude this is the reverse kinematic algorithm that is controlling this. The mystery is why it didn't happen when the test pose was performed at the test end?
But the mystery gets deeper. I puzzled over this behavior and observed it a number of times when I noticed that the LLEG servo was "twitching" (not "chattering") at the end of the test. I wondered if the servo was still trying to reach -90 and, as a result, it ignored or dropped subsequent commands. As a experiment, I lowered the target angle to one that should be achievable: -80 degrees. The second video (https://youtu.be/eLVuo9PSa1k) shows the result. Sure enough, the LLEG servo now returns to the test pose properly.
So the mystery is,
"What's happening to the servo?"
"Can the condition be detected?"
This behavior leads to undesirable results and potential disturbing collisions..
There's a clipping function to limit the joint angles:
If the joint collide with the body for a short period, the servo's self-protection will be triggered to reduce the force. After a cool down time, the force will resume. It will cause some delay if a follow-up instruction is sent right after that.
I haven't digested all of this but I do have some quick comments.
The sensor that sticks out from the BiBoard is the IR receiver (receives IR commands from the IR control/transmitter)
AFAIK, the servos currently have no way of communicating their position (angle) so the j token should just reply back with the position that the servo was last sent to. It really "should" be the same angle as what you initially told the servo to go to.
I sometimes have observed servo jittering when my robot is on the test stand (servos under no load) so that may be what you are seeing. I believe the Bittle servos are digital which means they may contain a built-in PID-type of feedback control loop to maintain the requested angle. Such a control loop can enter a hysteresis state which can appear as servo jitter. Perhaps the Petoi team can confirm if these servos are have such an built-in control loop logic. If present, I could understand how sending the servo to an angle that it cannot reach would cause such control loop jitter.