Legacy Forum: Preserving Nearly 20 Years of Community History - A Time Capsule of Discussions, Memories, and Shared Experiences.

libavr/libbioloid C library for CM5 released!

Bioloid robot kit from Korean company Robotis; CM5 controller block, AX12 servos..
289 postsPage 3 of 201, 2, 3, 4, 5, 6 ... 20
289 postsPage 3 of 201, 2, 3, 4, 5, 6 ... 20

Post by StuartL » Wed Dec 24, 2008 2:19 pm

Post by StuartL
Wed Dec 24, 2008 2:19 pm

BillB wrote:After a session of debugging a modified version of the example.c code here are 2 quick tips for anyone using the LibBioloid.


Heehee. Oops :D

Tip 1: The servo units are in the range -512 to +511 and not 0 to 1023 (as used in the BCP & Motion Editor).


This was a conscious change as it allows the maths to work with zero being 'centre'.

The servo range can be adjusted back to the 0 to 1023 range by modifying the SERVO_MIN, SERVO_CENTRE and SERVO_MAX constants in dynamixel.h to 0,0,1023 respectively.


This is probably accurate but a) it's untested and b) the trig will probably break. I'd recommend using zero as centre instead.

Tip 2: If you have built your code on the Example.c and your servos are not reaching the intended position then it may because the line beginning "const robot_t FLASH robot" is limiting the servo angles.


This is my fault, I set those limits to illustrate how to set the limits in the const robot definition. I won't change the limits but I will add some comments. The change should be in by the time you read this and the cron job will archive an updated version overnight.

Edit: All done
BillB wrote:After a session of debugging a modified version of the example.c code here are 2 quick tips for anyone using the LibBioloid.


Heehee. Oops :D

Tip 1: The servo units are in the range -512 to +511 and not 0 to 1023 (as used in the BCP & Motion Editor).


This was a conscious change as it allows the maths to work with zero being 'centre'.

The servo range can be adjusted back to the 0 to 1023 range by modifying the SERVO_MIN, SERVO_CENTRE and SERVO_MAX constants in dynamixel.h to 0,0,1023 respectively.


This is probably accurate but a) it's untested and b) the trig will probably break. I'd recommend using zero as centre instead.

Tip 2: If you have built your code on the Example.c and your servos are not reaching the intended position then it may because the line beginning "const robot_t FLASH robot" is limiting the servo angles.


This is my fault, I set those limits to illustrate how to set the limits in the const robot definition. I won't change the limits but I will add some comments. The change should be in by the time you read this and the cron job will archive an updated version overnight.

Edit: All done
StuartL
Savvy Roboteer
Savvy Roboteer
Posts: 350
Joined: Mon Jun 04, 2007 3:46 pm
Location: Thatcham, Berkshire, UK

Post by RandomMatt » Wed Dec 24, 2008 3:47 pm

Post by RandomMatt
Wed Dec 24, 2008 3:47 pm

The reason we chose 0 to be the servo centre position is as follows...

If you have the servo so that you can read the ID number (i.e. connectors towards you and the horn at the top),
and you want it to point towards coordinate (x,y) (with (0,0) in the left-bottom),
then the angle you need to use (with our code) is atan2(x, y).
The reason we chose 0 to be the servo centre position is as follows...

If you have the servo so that you can read the ID number (i.e. connectors towards you and the horn at the top),
and you want it to point towards coordinate (x,y) (with (0,0) in the left-bottom),
then the angle you need to use (with our code) is atan2(x, y).
RandomMatt
Savvy Roboteer
Savvy Roboteer
Posts: 117
Joined: Sat Dec 20, 2008 11:16 pm

Post by siempre.aprendiendo » Wed Dec 24, 2008 7:41 pm

Post by siempre.aprendiendo
Wed Dec 24, 2008 7:41 pm

I think it's more easy with the 0 as the center position. I'm working (very slowly) in a little game and one on my "wishes" about the AX12+ were this feature :) Thanks!

The game is about the bioloid trying to detect a "touch" the two approaching Lego NXTs. With two 3DOF arms and 2DOF AX-S1 Head

Here a little diagram from one of my many rusty maths doubts O: - )


P.S. Yesterday I tried your great library on ubuntu (and aspire one, on the sofa... well... I'm on holidays) and it worked perfectly :)
I think it's more easy with the 0 as the center position. I'm working (very slowly) in a little game and one on my "wishes" about the AX12+ were this feature :) Thanks!

The game is about the bioloid trying to detect a "touch" the two approaching Lego NXTs. With two 3DOF arms and 2DOF AX-S1 Head

Here a little diagram from one of my many rusty maths doubts O: - )


P.S. Yesterday I tried your great library on ubuntu (and aspire one, on the sofa... well... I'm on holidays) and it worked perfectly :)
siempre.aprendiendo
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 559
Joined: Wed Aug 08, 2007 9:13 pm
Location: Barcelona

Post by RandomMatt » Fri Dec 26, 2008 11:06 am

Post by RandomMatt
Fri Dec 26, 2008 11:06 am

I've updated libbioloid to make allow easy changing of the centre position of the servos, you want r934 (and above).

Basically, it treats 0 as the centre position unless you tell it otherwise. If (like BillB) you'd like it to be consistent with the BCP / motion editor, just add -DSERVO_CENTRE=512 to the CFLAGS_AVR line of the makefile.

(and yes I have changed the meaning of the value SERVO_CENTRE, hopefully from the confusing to the clear).
I've updated libbioloid to make allow easy changing of the centre position of the servos, you want r934 (and above).

Basically, it treats 0 as the centre position unless you tell it otherwise. If (like BillB) you'd like it to be consistent with the BCP / motion editor, just add -DSERVO_CENTRE=512 to the CFLAGS_AVR line of the makefile.

(and yes I have changed the meaning of the value SERVO_CENTRE, hopefully from the confusing to the clear).
RandomMatt
Savvy Roboteer
Savvy Roboteer
Posts: 117
Joined: Sat Dec 20, 2008 11:16 pm

Post by RandomMatt » Mon Jan 05, 2009 10:11 pm

Post by RandomMatt
Mon Jan 05, 2009 10:11 pm

BillB wrote:Is there a streamlined way to transfer the compiled .Hex file to the CM5.?


Bill, because you ask so nicely... i've added a programming tool to libbioloid (and libcompat that it depends on).

The programmer works on my eeepc (Linux) as either a terminal, or as a device(*) programmer. The code compiles on OpenBSD on my sparc workstation; so the chances of it working on your Mac are high :wink:.

While it compiles on windows, it will not work very well - I'll try to convince Stuart to have a look at it (I don't have a windows box that is easy to test with!)

(*) by device: I mean either a CM5 or an AX12 (with a bit of faffing around).
BillB wrote:Is there a streamlined way to transfer the compiled .Hex file to the CM5.?


Bill, because you ask so nicely... i've added a programming tool to libbioloid (and libcompat that it depends on).

The programmer works on my eeepc (Linux) as either a terminal, or as a device(*) programmer. The code compiles on OpenBSD on my sparc workstation; so the chances of it working on your Mac are high :wink:.

While it compiles on windows, it will not work very well - I'll try to convince Stuart to have a look at it (I don't have a windows box that is easy to test with!)

(*) by device: I mean either a CM5 or an AX12 (with a bit of faffing around).
RandomMatt
Savvy Roboteer
Savvy Roboteer
Posts: 117
Joined: Sat Dec 20, 2008 11:16 pm

Post by BillB » Tue Jan 06, 2009 8:58 pm

Post by BillB
Tue Jan 06, 2009 8:58 pm

Christmas break over… even managed to fit in some C coding :) but no internet connectivity :cry: .

Matt - the more I use your Bioloid Library the more I like it thak you so much for releasing it, there are many features of the 'Supervisor' that has saved my battery, servo (and even prevented a potential short cuircuit) .

I now have all my Inverse Kinematics working on board the CM5. I was surprised how compact and efficient I could make the IK code by using some well designed lookup tables (insired by your Trig tables). My IK is now really quite fast (and there is still further scope for optimisation.

When running the robot without the line "timer_delay(1);" the robot limbs move very smoothly, but when I introduce this line (which reduced the the servos be updated at only 40Hz) the robot movements are more jerky, particularly for slow moving gaits.

I have concluded that the reason for this is that the Servos are moving too fast and need to be slowed down.

I am using the function "dx_getstance" to set the position of the servos. But it does not appear to support setting the position at the same time. The Speed and Position bytes are next to each other on the AX12 data table so it should be efficient to set the Speed and Position in the same sync write.

Matt - before I reinvent the wheel are there any functions in your library ,that I have perhaps missed, that can set the Speed & Position in the same sync write? It would be very useful to be able to do this in order to some Point-To-Point moves (where the servos move at different speed but arrive at their destination at the same time).
Christmas break over… even managed to fit in some C coding :) but no internet connectivity :cry: .

Matt - the more I use your Bioloid Library the more I like it thak you so much for releasing it, there are many features of the 'Supervisor' that has saved my battery, servo (and even prevented a potential short cuircuit) .

I now have all my Inverse Kinematics working on board the CM5. I was surprised how compact and efficient I could make the IK code by using some well designed lookup tables (insired by your Trig tables). My IK is now really quite fast (and there is still further scope for optimisation.

When running the robot without the line "timer_delay(1);" the robot limbs move very smoothly, but when I introduce this line (which reduced the the servos be updated at only 40Hz) the robot movements are more jerky, particularly for slow moving gaits.

I have concluded that the reason for this is that the Servos are moving too fast and need to be slowed down.

I am using the function "dx_getstance" to set the position of the servos. But it does not appear to support setting the position at the same time. The Speed and Position bytes are next to each other on the AX12 data table so it should be efficient to set the Speed and Position in the same sync write.

Matt - before I reinvent the wheel are there any functions in your library ,that I have perhaps missed, that can set the Speed & Position in the same sync write? It would be very useful to be able to do this in order to some Point-To-Point moves (where the servos move at different speed but arrive at their destination at the same time).
BillB
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 232
Joined: Sun Aug 06, 2006 1:00 am
Location: Hampshire, UK

Post by BillB » Tue Jan 06, 2009 9:04 pm

Post by BillB
Tue Jan 06, 2009 9:04 pm

My tips for using Matt fabulous Bioloid library continue:

Tip #3: The CM5 has a limited memory, and if you are using large lookup tables you will soon fill up the memory. Unfortunately the compiler will not warn you that you have exceeded the memory and strange things will happen like: Supervisor will stop the robot claiming that there is a large negative voltage. So if this happens then try and reduce the size of the look up tables before you pull your hair out.
My tips for using Matt fabulous Bioloid library continue:

Tip #3: The CM5 has a limited memory, and if you are using large lookup tables you will soon fill up the memory. Unfortunately the compiler will not warn you that you have exceeded the memory and strange things will happen like: Supervisor will stop the robot claiming that there is a large negative voltage. So if this happens then try and reduce the size of the look up tables before you pull your hair out.
BillB
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 232
Joined: Sun Aug 06, 2006 1:00 am
Location: Hampshire, UK

Post by RandomMatt » Wed Jan 07, 2009 8:44 am

Post by RandomMatt
Wed Jan 07, 2009 8:44 am

I've updated libcompat, so now the programmer (in libbioloid) works under windows as well as unix. Basically, you want to run a command like (from the example directory):

in windows:
..\tools\programmer -t com1: example.bin

in unix:
../tools/programmer -t /dev/ttyUSB0 example.bin

and it should just work.

BillB: If you've tried, does it work on your Mac?
I've updated libcompat, so now the programmer (in libbioloid) works under windows as well as unix. Basically, you want to run a command like (from the example directory):

in windows:
..\tools\programmer -t com1: example.bin

in unix:
../tools/programmer -t /dev/ttyUSB0 example.bin

and it should just work.

BillB: If you've tried, does it work on your Mac?
RandomMatt
Savvy Roboteer
Savvy Roboteer
Posts: 117
Joined: Sat Dec 20, 2008 11:16 pm

Post by RandomMatt » Wed Jan 07, 2009 9:00 am

Post by RandomMatt
Wed Jan 07, 2009 9:00 am

BillB wrote:My tips for using Matt fabulous Bioloid library continue:

Tip #3: The CM5 has a limited memory, and if you are using large lookup tables you will soon fill up the memory. Unfortunately the compiler will not warn you that you have exceeded the memory and strange things will happen like: Supervisor will stop the robot claiming that there is a large negative voltage. So if this happens then try and reduce the size of the look up tables before you pull your hair out.


One fact: the CM5 uses a Mega128, so it has 4096 bytes of ram. In general there are three tricks that can help keep your program's ram use that low:

1) If you type "make size" you can then see how big your programs static data (i.e. global variables) is. You'll need to add the figures for "data" and "bss" together (the data segment contains all the initialised global variables, bss the uninitialised ones). You could also try running avr-nm on your elf file.

2) You can try lowering the value for UART_BUFSIZE (defaults to 256). You can do this by adding, for example, "-DUART_BUFSIZE=64" to CFLAGS_AVR in the Makefile. This will reduce the size of the buffers used for both serial links - you can reduce the buffer size to 1 and the code will still work, but more slowly (you can tell when this happens because the play led will flicker).

3) Stick static data into flash, look at the implementation of sin() for how to do this.
BillB wrote:My tips for using Matt fabulous Bioloid library continue:

Tip #3: The CM5 has a limited memory, and if you are using large lookup tables you will soon fill up the memory. Unfortunately the compiler will not warn you that you have exceeded the memory and strange things will happen like: Supervisor will stop the robot claiming that there is a large negative voltage. So if this happens then try and reduce the size of the look up tables before you pull your hair out.


One fact: the CM5 uses a Mega128, so it has 4096 bytes of ram. In general there are three tricks that can help keep your program's ram use that low:

1) If you type "make size" you can then see how big your programs static data (i.e. global variables) is. You'll need to add the figures for "data" and "bss" together (the data segment contains all the initialised global variables, bss the uninitialised ones). You could also try running avr-nm on your elf file.

2) You can try lowering the value for UART_BUFSIZE (defaults to 256). You can do this by adding, for example, "-DUART_BUFSIZE=64" to CFLAGS_AVR in the Makefile. This will reduce the size of the buffers used for both serial links - you can reduce the buffer size to 1 and the code will still work, but more slowly (you can tell when this happens because the play led will flicker).

3) Stick static data into flash, look at the implementation of sin() for how to do this.
RandomMatt
Savvy Roboteer
Savvy Roboteer
Posts: 117
Joined: Sat Dec 20, 2008 11:16 pm

Post by RandomMatt » Wed Jan 07, 2009 1:22 pm

Post by RandomMatt
Wed Jan 07, 2009 1:22 pm

BillB wrote:Matt - the more I use your Bioloid Library the more I like it thak you so much for releasing it.


That's good to know. One day Stuart and I might even get as far as documenting it.

BillB wrote:I have concluded that the reason for this is that the Servos are moving too fast and need to be slowed down.

I am using the function "dx_getstance" to set the position of the servos. But it does not appear to support setting the position at the same time. The Speed and Position bytes are next to each other on the AX12 data table so it should be efficient to set the Speed and Position in the same sync write.

Matt - before I reinvent the wheel are there any functions in your library ,that I have perhaps missed, that can set the Speed & Position in the same sync write?


Short answer... no there is not (currently) a library call for that.


Long answer... I'm not sure you really want to do it that way.

A problem is that simple servo controls (like the one in AX-12) suffer from serious tracking error - which unfortunately is what we really care about. For what it is worth, PID and PIV controllers also suffer from the same problem.

The quick, easy, fix would be set the compliance curves to be a bit softer (dx_setcompliance) - then you'll have worse tracking error, but smoother servo movement. Now I come to think about this, that sounds like the same effect as setting a max speed as you suggested.

The real fix would be to write some servo firmware and put a decent control loop in there (which, incidentally, is what I'm currently up to). On the subject of better servo firmware, my servos interpolate the 40Hz position updates into 1000Hz positions for its control loop.


A Secondary issue is... how much jitter in the goal positions is there? Obviously the servo is only as good as the input data! (Obviously my trig functions may contribute to this error... so: sorry if that is the case)
BillB wrote:Matt - the more I use your Bioloid Library the more I like it thak you so much for releasing it.


That's good to know. One day Stuart and I might even get as far as documenting it.

BillB wrote:I have concluded that the reason for this is that the Servos are moving too fast and need to be slowed down.

I am using the function "dx_getstance" to set the position of the servos. But it does not appear to support setting the position at the same time. The Speed and Position bytes are next to each other on the AX12 data table so it should be efficient to set the Speed and Position in the same sync write.

Matt - before I reinvent the wheel are there any functions in your library ,that I have perhaps missed, that can set the Speed & Position in the same sync write?


Short answer... no there is not (currently) a library call for that.


Long answer... I'm not sure you really want to do it that way.

A problem is that simple servo controls (like the one in AX-12) suffer from serious tracking error - which unfortunately is what we really care about. For what it is worth, PID and PIV controllers also suffer from the same problem.

The quick, easy, fix would be set the compliance curves to be a bit softer (dx_setcompliance) - then you'll have worse tracking error, but smoother servo movement. Now I come to think about this, that sounds like the same effect as setting a max speed as you suggested.

The real fix would be to write some servo firmware and put a decent control loop in there (which, incidentally, is what I'm currently up to). On the subject of better servo firmware, my servos interpolate the 40Hz position updates into 1000Hz positions for its control loop.


A Secondary issue is... how much jitter in the goal positions is there? Obviously the servo is only as good as the input data! (Obviously my trig functions may contribute to this error... so: sorry if that is the case)
RandomMatt
Savvy Roboteer
Savvy Roboteer
Posts: 117
Joined: Sat Dec 20, 2008 11:16 pm

Post by BillB » Thu Jan 08, 2009 9:22 pm

Post by BillB
Thu Jan 08, 2009 9:22 pm

Random Matt wrote:
I've updated libcompat, so now the programmer (in libbioloid) works under windows as well as unix. Basically, you want to run a command like (from the example directory):


Well it certianly compiles fine on the Mac and I can run the program. Unfortunately I have lost the USB to Serial cable I used on my Mac and am having to use an older one on a PC which does not seem to like my Mac. Once I find my (or buy a new) Mac compatible USB to Serial adapter I will confirm that it works.
Random Matt wrote:
I've updated libcompat, so now the programmer (in libbioloid) works under windows as well as unix. Basically, you want to run a command like (from the example directory):


Well it certianly compiles fine on the Mac and I can run the program. Unfortunately I have lost the USB to Serial cable I used on my Mac and am having to use an older one on a PC which does not seem to like my Mac. Once I find my (or buy a new) Mac compatible USB to Serial adapter I will confirm that it works.
BillB
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 232
Joined: Sun Aug 06, 2006 1:00 am
Location: Hampshire, UK

Post by BillB » Thu Jan 08, 2009 9:27 pm

Post by BillB
Thu Jan 08, 2009 9:27 pm

Matt - do you have a code snippit that shows how to read from the CM5 Uart used for Zigbee/Bluetooth. I am trying to decipher your code in the UART.c file but not having much luck.

Many thanks

Bill
Matt - do you have a code snippit that shows how to read from the CM5 Uart used for Zigbee/Bluetooth. I am trying to decipher your code in the UART.c file but not having much luck.

Many thanks

Bill
BillB
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 232
Joined: Sun Aug 06, 2006 1:00 am
Location: Hampshire, UK

Post by RandomMatt » Thu Jan 08, 2009 10:08 pm

Post by RandomMatt
Thu Jan 08, 2009 10:08 pm

uart is a bit low level, you want to look in sio_input ans sio_output (you can just include sio.h if you want both input and output). If you are curious - sio standards for Serial Input Output.

getchar, ungetchar and lastchar are defined in sio_input.h
printf, putchar, puts and fflush are defined in sio_output.h
most of these behave as you expect, lastchar is a non-blocking version of getchar, and fflush doesn't take a parameter.

The code in sio_*.c calls the code in uart.c to do the actual data transfers . (uart.c is very low level, which is why it doesn't make much sense unless you have the mega128 pdf (from atmel) open!)

As a aside uart_init - called from init - sets up a timer that checks if you have the PC-link wire plugged in, and if you don't automatically switches to reading from the zigbee.

The CM5 is wired so that output is to both the (RS232) PC-link and the zigbee.
uart is a bit low level, you want to look in sio_input ans sio_output (you can just include sio.h if you want both input and output). If you are curious - sio standards for Serial Input Output.

getchar, ungetchar and lastchar are defined in sio_input.h
printf, putchar, puts and fflush are defined in sio_output.h
most of these behave as you expect, lastchar is a non-blocking version of getchar, and fflush doesn't take a parameter.

The code in sio_*.c calls the code in uart.c to do the actual data transfers . (uart.c is very low level, which is why it doesn't make much sense unless you have the mega128 pdf (from atmel) open!)

As a aside uart_init - called from init - sets up a timer that checks if you have the PC-link wire plugged in, and if you don't automatically switches to reading from the zigbee.

The CM5 is wired so that output is to both the (RS232) PC-link and the zigbee.
RandomMatt
Savvy Roboteer
Savvy Roboteer
Posts: 117
Joined: Sat Dec 20, 2008 11:16 pm

Post by BillB » Fri Jan 09, 2009 11:07 am

Post by BillB
Fri Jan 09, 2009 11:07 am

Matt wrote:
The code in sio_*.c calls the code in uart.c to do the actual data transfers . (uart.c is very low level, which is why it doesn't make much sense unless you have the mega128 pdf (from atmel) open!)


Ah, that will be the problem I was looking in the wrong place( I was getting very worried when I looked at uart.c).

Once again Matt you have excelled in making programming the Bioloid in C much, much easier. Well done.
Matt wrote:
The code in sio_*.c calls the code in uart.c to do the actual data transfers . (uart.c is very low level, which is why it doesn't make much sense unless you have the mega128 pdf (from atmel) open!)


Ah, that will be the problem I was looking in the wrong place( I was getting very worried when I looked at uart.c).

Once again Matt you have excelled in making programming the Bioloid in C much, much easier. Well done.
BillB
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 232
Joined: Sun Aug 06, 2006 1:00 am
Location: Hampshire, UK

Post by BillB » Fri Jan 09, 2009 11:19 am

Post by BillB
Fri Jan 09, 2009 11:19 am

Matt,

I am sending 2 bytes to the CM5 and I assume they are both being stored in the Uart buffer. My problem is that I do not seem to be able to use lastchar() and getchar() to step through the contents of the buffer.

I am using the following code snippet to try and iterate through the buffer, but it gets blocked in the getchar() once it has got to the end of the buffer:

Code: Select all
char c;
if(lastchar() != '\0')
{
   do{
       c = getchar();
       // Process the data here
   } while (c!= '\0');         
}



Is there anyway to determine the size of the buffer, or a way to know when the getchar() has reached the end of the buffer. The immediate fix is to replace the while condition with"(c != lastchar)", but I can not always guarantee that the last char is unique to the end of a message packet.
Matt,

I am sending 2 bytes to the CM5 and I assume they are both being stored in the Uart buffer. My problem is that I do not seem to be able to use lastchar() and getchar() to step through the contents of the buffer.

I am using the following code snippet to try and iterate through the buffer, but it gets blocked in the getchar() once it has got to the end of the buffer:

Code: Select all
char c;
if(lastchar() != '\0')
{
   do{
       c = getchar();
       // Process the data here
   } while (c!= '\0');         
}



Is there anyway to determine the size of the buffer, or a way to know when the getchar() has reached the end of the buffer. The immediate fix is to replace the while condition with"(c != lastchar)", but I can not always guarantee that the last char is unique to the end of a message packet.
BillB
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 232
Joined: Sun Aug 06, 2006 1:00 am
Location: Hampshire, UK

PreviousNext
289 postsPage 3 of 201, 2, 3, 4, 5, 6 ... 20
289 postsPage 3 of 201, 2, 3, 4, 5, 6 ... 20