@kurte
Thanks for checking. If it works can you do me one favor just to see if there is a problem with the gait code? Can you try a couple of the different gaits? Shouldn’t take too long. Really curious if it works. If it doesn’t not sure what’s next?
Not a problem - know you are busy today. Just wanted to ask before I forgot. Doing backups now before I loose a hard drive - don’t like gotchas Have fun.
Probably test first with servo test program. The coxa’s could be wrong, but we never move them, so I am going to introduce some movement to see
As for the offsets will try looking at the legs after running ‘i’ and see where they all are…
First pass, I updated the sketch to move the Coxa…
Also in the ‘i’ command I added code that after each move if there is Serial.available() it pauses until you hit some more characters… So you can stop things and take look.
Will push up once this is fixed.
Currently stance:
#define RF_STANCE_COUNT 7
int16_t rf_stance [RF_STANCE_COUNT][3] =
{
{0, -900, -600}, //Low
// 0, -900, 510 degrees
{100, -450, -300}, //mid Low
{200, 0, 0}, //Med
{0, 450, 450}, //High
{-100, 0, 0}, //Med
{-200, -450, -300}, //mid Low
{0, -900, -600} //Low
};
And output in run up to this:
Cmd: i
Checks Status wait loops 1 in us: 15406
Print Servo Positions Joint(Goal, timed, end)
C:1(0, 0, 0) F:3(-900, 0, -901) T:5(-600, 0, -598)
C:13(0, 0, -1) F:15(-900, 0, -902) T:17(-600, 0, -601)
C:1(0, 0, 0) F:9(-900, 0, -897) T:11(-600, 0, -598)
C:2(0, 0, -2) F:4(-900, 0, -899) T:6(-600, 0, -599)
C:14(0, 0, 2) F:16(-900, 0, -900) T:18(-600, 0, -600)
C:2(0, 0, -2) F:10(-900, 0, -900) T:12(-600, 0, -601)
Checks Status wait loops 48 in us: 499500
Print Servo Positions Joint(Goal, timed, end)
C:1(100, 31, 97) F:3(-450, -783, -507) T:5(-300, -498, -297)
C:13(100, 50, 98) F:15(-450, -729, -451) T:17(-300, -506, -306)
C:1(100, 35, 97) F:9(-450, -783, -512) T:11(-300, -507, -307)
C:2(100, 65, 98) F:4(-450, -720, -449) T:6(-300, -459, -292)
C:14(100, 53, 97) F:16(-450, -728, -459) T:18(-300, -453, -291)
C:2(100, 69, 98) F:10(-450, -723, -461) T:12(-300, -444, -288)
get status for Femur servo:10 for leg:5 failed on loop: 28
get status for Femur servo:16 for leg:4 failed on loop: 30
Checks Status wait loops 31 in us: 588237
Print Servo Positions Joint(Goal, timed, end)
C:1(200, 148, 198) F:3(0, -343, 1) T:5(0, -202, 0)
C:13(200, 169, 199) F:15(0, -323, 2) T:17(0, -201, 1)
C:1(200, 153, 197) F:9(0, -335, 3) T:11(0, -203, 1)
C:2(200, 177, 200) F:4(0, -311, 1) T:6(0, -194, 1)
C:14(200, 173, 198) F:16(0, -319, 1) T:18(0, -187, 3)
C:2(200, 181, 200) F:10(0, -303, 1) T:12(0, -196, -1)
get status for Femur servo:4 for leg:3 failed on loop: 8
Checks Status wait loops 51 in us: 520694
Print Servo Positions Joint(Goal, timed, end)
C:1(0, 103, 2) F:3(450, 100, 394) T:5(450, 119, 424)
C:13(0, 78, -2) F:15(450, 109, 419) T:17(450, 121, 425)
C:1(0, 96, 3) F:9(450, 102, 392) T:11(450, 120, 423)
C:2(0, 94, 0) F:4(450, 127, 429) T:6(450, 126, 424)
C:14(0, 73, -1) F:16(450, 120, 426) T:18(450, 118, 416)
C:2(0, 88, 0) F:10(450, 137, 436) T:12(450, 124, 424)
*** Paused hit any key to continue ***
get status for Tibia servo:5 for leg:0 failed on loop: 27
Checks Status wait loops 33 in us: 501713
Print Servo Positions Joint(Goal, timed, end)
C:1(-100, -63, -98) F:3(0, 314, 46) T:5(0, 291, 18)
C:13(-100, -45, -95) F:15(0, 282, 16) T:17(0, 308, 37)
C:1(-100, -67, -98) F:9(0, 296, 33) T:11(0, 290, 31)
C:2(-100, -52, -95) F:4(0, 278, 17) T:6(0, 277, 11)
C:14(-100, -65, -96) F:16(0, 280, 15) T:18(0, 281, 20)
C:2(-100, -56, -95) F:10(0, 274, 17) T:12(0, 259, -8)
*** Paused hit any key to continue ***
get status for Femur servo:9 for leg:2 failed on loop: 36
Checks Status wait loops 37 in us: 538881
Print Servo Positions Joint(Goal, timed, end)
C:1(-200, -179, -200) F:3(-450, -106, -419) T:5(-300, -101, -300)
C:13(-200, -144, -197) F:15(-450, -122, -447) T:17(-300, -93, -299)
C:1(-200, -183, -200) F:9(-450, -116, -428) T:11(-300, -101, -298)
C:2(-200, -184, -200) F:4(-450, -129, -449) T:6(-300, -102, -299)
C:14(-200, -186, -203) F:16(-450, -135, -457) T:18(-300, -111, -302)
C:2(-200, -188, -200) F:10(-450, -148, -452) T:12(-300, -86, -298)
*** Paused hit any key to continue ***
EDIT
Made changes for 1) picture looks better.
As for 2) not sure yet. Maybe chicken and Egg… That is if we told them to go in opposite directions by the Gyre, than maybe same directions is fine… Then maybe not…
Pushed changes back up
Cool - definitely looks better. May not need any other changes. Now I guess the real test is going to be see if the gait stuff works or have to start porting over to zenta sketch set up.
Thanks for checking even though I am limited real curious if it works.
Made changes in Phoenix code, still same issue.
May be several hours before I can look much more… But getting closer
But I am thinking that it may be in the differences in processing the left and right legs… That is if we look at:
for (LegIndex = 0; LegIndex < (CNT_LEGS / 2); LegIndex++) {
DoBackgroundProcess();
BodyFK(-LegPosX[LegIndex] + g_InControlState.BodyPos.x + GaitPosX[LegIndex] - TotalTransX,
LegPosZ[LegIndex] + g_InControlState.BodyPos.z + GaitPosZ[LegIndex] - TotalTransZ,
LegPosY[LegIndex] + g_InControlState.BodyPos.y + GaitPosY[LegIndex] - TotalTransY,
GaitRotY[LegIndex], LegIndex);
LegIK(LegPosX[LegIndex] - g_InControlState.BodyPos.x + BodyFKPosX - (GaitPosX[LegIndex] - TotalTransX),
LegPosY[LegIndex] + g_InControlState.BodyPos.y - BodyFKPosY + GaitPosY[LegIndex] - TotalTransY,
LegPosZ[LegIndex] + g_InControlState.BodyPos.z - BodyFKPosZ + GaitPosZ[LegIndex] - TotalTransZ, LegIndex);
}
//Do IK for all Left legs
for (LegIndex = (CNT_LEGS / 2); LegIndex < CNT_LEGS; LegIndex++) {
DoBackgroundProcess();
BodyFK(LegPosX[LegIndex] - g_InControlState.BodyPos.x + GaitPosX[LegIndex] - TotalTransX,
LegPosZ[LegIndex] + g_InControlState.BodyPos.z + GaitPosZ[LegIndex] - TotalTransZ,
LegPosY[LegIndex] + g_InControlState.BodyPos.y + GaitPosY[LegIndex] - TotalTransY,
GaitRotY[LegIndex], LegIndex);
LegIK(LegPosX[LegIndex] + g_InControlState.BodyPos.x - BodyFKPosX + GaitPosX[LegIndex] - TotalTransX,
LegPosY[LegIndex] + g_InControlState.BodyPos.y - BodyFKPosY + GaitPosY[LegIndex] - TotalTransY,
LegPosZ[LegIndex] + g_InControlState.BodyPos.z - BodyFKPosZ + GaitPosZ[LegIndex] - TotalTransZ, LegIndex);
}
So it may be reversion some of the stuff already.
Got it. Just for doc purposes before I forget I just look in the other version and noticed this when Legs are done:
**//There was an old error in this code when calling the BodyFK() should be "+ g_InControlState.BodyPos.x" for both left and right legs** BodyFK(-LegPosX[LegIndex] - LegRotYxPos[LegIndex] + g_InControlState.BodyPos.x + g_InControlState.DWtransX + GaitPosX[LegIndex],//- TotalTransX LegPosZ[LegIndex] - LegRotYzPos[LegIndex] + g_InControlState.BodyPos.z + g_InControlState.DWtransZ + GaitPosZ[LegIndex],//- TotalTransZ LegPosY[LegIndex] + g_InControlState.BodyPos.y + GaitPosY[LegIndex],//- TotalTransY GaitRotY[LegIndex], LegIndex, 0);//Balance rotation only
Could be the problem - maybe its almost time…
Now go have fun with your other diversions.
Taking a break to get ready for other diversion.
Wondered if maybe our GYRE stuff was interfering. Like it already has a defined inversion even if none defined…
So I updated the code a bit:
In the CFG file, I defined:
#define SERVOS_DO_INVERSION
And in the main code I check that and don’t do any inversion stuff
void StartUpdateServos()
{
byte LegIndex;
// First call off to the init...
g_ServoDriver.BeginServoUpdate(); // Start the update
for (LegIndex = 0; LegIndex < CNT_LEGS; LegIndex++) {
#ifdef c4DOF
g_ServoDriver.OutputServoInfoForLeg(LegIndex,
cCoxaInv[LegIndex] ? -CoxaAngle1[LegIndex] : CoxaAngle1[LegIndex],
cFemurInv[LegIndex] ? -FemurAngle1[LegIndex] : FemurAngle1[LegIndex],
cTibiaInv[LegIndex] ? -TibiaAngle1[LegIndex] : TibiaAngle1[LegIndex],
cTarsInv[LegIndex] ? -TarsAngle1[LegIndex]) : TarsAngle1[LegIndex]);
#else
#ifdef SERVOS_DO_INVERSION
g_ServoDriver.OutputServoInfoForLeg(LegIndex,
cCoxaAngle1[LegIndex],
FemurAngle1[LegIndex],
TibiaAngle1[LegIndex]);
#else
g_ServoDriver.OutputServoInfoForLeg(LegIndex,
cCoxaInv[LegIndex] ? -CoxaAngle1[LegIndex] : CoxaAngle1[LegIndex],
cFemurInv[LegIndex] ? -FemurAngle1[LegIndex] : FemurAngle1[LegIndex],
cTibiaInv[LegIndex] ? -TibiaAngle1[LegIndex] : TibiaAngle1[LegIndex]);
#endif
#endif
}
#ifdef cTurretRotPin
g_ServoDriver.OutputServoInfoForTurret(g_InControlState.TurretRotAngle1, g_InControlState.TurretTiltAngle1); // fist just see if it will talk
#endif
}
And Now when I hit the Hat UP, all of the legs go in the one direction…
BUT: their now the leg offsets are screwed up: So I will adjust…
Also want to play with the sitdown and stand up positions. As it is now more like stand up and tippy toes…
Sounds like you are having fun now
You might want to check this out in the cfg:
//--------------------------------------------------------------------
//[START POSITIONS FEET]
#define cHexInitXZ 131
#define CHexInitXZCos60 73 // COS(56) = .707
#define CHexInitXZSin60 109 // sin(56) = .707
#define CHexInitY 116 //30// Lets try some multi leg positions depending on height settings.
#define CNT_HEX_INITS 2
#define MAX_BODY_Y 120
Got the legs to do to at least go up in down in the right position by changing this stuff. Also think I changed this line from 50 to 150 in setup:
g_InControlState.LegLiftHeight = 150;
@kurte
First post for the day I guess. I just posted a version of the Zenta_LSS_Phoenix_PhantomX_float code for LSS - it does compile displays logo on the ST7789 but hangs after that - doesn’t seem to get to BT joystick pairing.
@mjs513 - Sounds great.
I just synced to your version and will give it a try.
Wondering if I should switch back to my previous board with the ST7789 connector on it… and/or maybe see how the data looks on an a monochrome display that can plug in to the QWIIC connectors (which are the wrong ones :0 )
I have at least two: https://www.sparkfun.com/products/15890 as well as a small SSD1306 version.
@kurte - probably the only display I don’t have.
Not to worry about the qwiic connectors being wrong - can always get some of these: SparkFun Qwiic Adapter - DEV-14495 - SparkFun Electronics. I already a few laying around for just such cases
Good Morning (at least here) @cbenson @dialfonzo and all. Hope everyone is doing well and is well!
I am thinking about taking a break from working on the Hexapod stuff and get back to some other diversions which I have been neglecting.
On the Teensy front There are some really interesting capabilities that we are very close to being able to hopefully merge into the next release of Teensyduino. From the ability to plug in your Teensy to a PC and have some storages on you PC be accessible on your PC. And likewise on T3.6 and T4.x the ability to plug in things like USB drives and memory sticks and be able to use them on your Teensy… Plus continue to do some more work on the Bluetooth and Joysticks…
This will hopefully give everyone else a chance to digest all of the questions and observations that @cyberpalin and myself have had with working these servos. Hopefully with some of these issues, your Servo experts can offer some insights and solutions and potentially a new version of firmware to address them.
I would assume that RobotShop has one or more Hexapod setups in shop that you can tryout the different programs that we have posted and you can see and confirm the issues for yourself. With this setup you can then see if any changes made to the servos solve these issues and or you can make suggestions on ways to avoid them.
As part of your Servo Beta I would have assumed that you would have made simple test setups like, maybe make one leg (or arm or…) with RC Servos and a very simper one with LSS servos and mounted them next to each other. Then take a simple SSC-32 program to maybe emulate the movements of one leg, maybe something like 8-10 positions to rotate through with timings… With things like: #1P1500#2P1500#3P1500T250\r …
Then convert the Pulses to angles for the new LSS servos… Have these both connected to any micro-controller you have that can talk to your LSS servos and an SSC-32 in the same program and simply output one step at a time to both Serial ports and one wait that matches the T of your move and both legs should move the same.
Do you have some such test? If not, that really may be the next logical step to do!
If you do have such a test, it would be interesting to see video and code for it. It could be rather simple to write. I might still hack one up out of curiosity.
Yesterday I was trying to setup a simple version of this with just one servo on each, but looks like my SSC-32u may be dead along with most if not all of my old 6v batteries. Also the SSC-32u did not like any of my older 6v wall warts. I may still be able to hook up an older SSC-32, Not sure sure yet. But I am curious.
Again I hope all are doing well.
I was hoping to try this at some point. I have the original Dualshock PS4 controller. I read there were some issues, will that work ?
It should, that is what we originally tested with. We do have a couple of different clones we are trying to get working. I maybe have one other by Voyee, but making it work may have busted the original… But the original has been working with the Teensyduino release
Note the one I have (ordered in 2019) is:
https://smile.amazon.com/gp/product/B01MD19OI2
Pretty much what I am working with now and that is working well. The one I have I got from amazon: Amazon.com: DualShock 4 - White: Video Games which is an original DualShock.
We are still working on issues with the PS4 clones as @kurte mentioned.
@xan new controller looks pretty neat and looks like it can be used for other things as well So @xan if you see this any parts list or layout for the cuts on the top panel would be appreciated
Indeed there are / were quite a few setups for testing the LSS, though group move commands like #1P1500#2P1500#3P1500T250\r were unfortunately not implemented before the release. The group move does provide some nice functionality indeed. Regarding comparing the output physically from and SSC-32 based RC robot to the same robot using LSS, this was only done indirectly.
We encounter the same issues of batteries being left to discharge for extended periods of time when unused. Not sure why the wall wart wouldn’t work though.
There is progress being made regarding communication speeds and reducing errors and all BETA groups will be made aware of new firmware as soon as it can be shared. In order to expedite this, only limited internal testing will be done, and hopefully our BETA testers will be able to find any new issues which may arise.
Thanks,
I understand the group move was not yet implemented. So the side by side test could be slightly modified to add the T command after each Servo in the case of the LSS servos.
Again what am curious about if code up to mimic each other, do both objects move the same.
One reason I ask this is again we ran simple test in program to move lets say 45 degrees in quarter second, and using the query it often took about .4 seconds to say it arrived. And when I queried the servos at the quarter second they were not there…
Again I have not setup the SSC-32 yet, but here is for example a simple sketch, where I do sort of like your sweep program, but instead break it up into sub-moves which are timed. That is I use the moveT command with the time and I pause by that time. So I bet if I ran it on something like an HS-645mg servo I expect I will get a smooth continuous rotate sweeping back and forth.
Currently with the new ST-1 that I purchased last week, the move at times for lack of better term sputters. Also I can not run the test for long as Annie reacts.
#include <LSS.h>
// ID set to default LSS ID = 0
#define LSS_ID (0)
#define LSS_BAUD (LSS_DefaultBaud)
// Choose the proper serial port for your platform
//#define LSS_SERIAL (Serial) // ex: Many Arduino boards
#define LSS_SERIAL (Serial1) // ex: Teensy
LSS myLSS = LSS(LSS_ID);
#define SERVO_MAX 1800
#define SERVO_MIN -1800
#define NUMBER_STEPS 36
#define DELTA_PER_MOVE ((SERVO_MAX - SERVO_MIN)/ NUMBER_STEPS)
#define TIME_PER_STEP (4000/NUMBER_STEPS)
void setup()
{
while (!Serial && millis() < 5000) ;
Serial.println("Servo continuous time moves test");
Serial.println("Press any key to pause test");
// Initialize the LSS bus
LSS::initBus(LSS_SERIAL, LSS_BAUD);
// Initialize LSS to position 0.0 °
myLSS.move(SERVO_MIN);
// Wait for it to get there
delay(2000);
}
void pause_test() {
if (Serial.available()) {
Serial.println("Test Paused, press any key to continue");
while (Serial.read() != -1) ;
while (Serial.read() == -1) ;
while (Serial.read() != -1) ;
}
}
void loop()
{
for (int servo_pos = SERVO_MIN; servo_pos < SERVO_MAX; servo_pos += DELTA_PER_MOVE) {
pause_test();
myLSS.moveT(servo_pos, TIME_PER_STEP);
delay(TIME_PER_STEP);
}
for (int servo_pos = SERVO_MAX; servo_pos > SERVO_MIN; servo_pos -= DELTA_PER_MOVE) {
pause_test();
myLSS.moveT(servo_pos, TIME_PER_STEP);
delay(TIME_PER_STEP);
}
}
Which should run on any of your setups. I also pushed up this program to my test sketch project.
I am glad that they are making progress on the communications. Look forward to see what all they come up with.
Kurt
Thanks @kurte and @cyberpalin
I will run and see what obstacles I hit… Will keep you all updated…
ooh this is the 800th post… I wonder if there is any other topic which is as long…