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

Example.c

Bioloid robot kit from Korean company Robotis; CM5 controller block, AX12 servos..
11 postsPage 1 of 1
11 postsPage 1 of 1

Example.c

Post by billyzelsnack » Sun Jan 14, 2007 12:02 am

Post by billyzelsnack
Sun Jan 14, 2007 12:02 am

I think I might try yet another route.. haha. I really would like it so the programs I write be useable by others without special hardware. So I am now investigating swapping out the CM5 firmware with something else.

I finally got example.c compiled and loaded. Apparently WinAVR + Vista is a mess. I put it on a XP machine and it just worked first try.

So now the next step is to try and get the uC to see things I am sending over the stock serial cable. Hopefully I'll be more successful than my previous attempts when using just the behavior programs. After that I'll put together a simple PC side C API and demo app to communicate with the new firmware.

I also would like to make something that interacts with the bootloader a little more user friendly. Something so that an end-user would be more comfortable using and would make it easier to install new firmware and revert back to the bioloid firmware quickly.
I think I might try yet another route.. haha. I really would like it so the programs I write be useable by others without special hardware. So I am now investigating swapping out the CM5 firmware with something else.

I finally got example.c compiled and loaded. Apparently WinAVR + Vista is a mess. I put it on a XP machine and it just worked first try.

So now the next step is to try and get the uC to see things I am sending over the stock serial cable. Hopefully I'll be more successful than my previous attempts when using just the behavior programs. After that I'll put together a simple PC side C API and demo app to communicate with the new firmware.

I also would like to make something that interacts with the bootloader a little more user friendly. Something so that an end-user would be more comfortable using and would make it easier to install new firmware and revert back to the bioloid firmware quickly.
billyzelsnack
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 618
Joined: Sat Dec 30, 2006 1:00 am

Post by JonHylands » Sun Jan 14, 2007 12:12 am

Post by JonHylands
Sun Jan 14, 2007 12:12 am

If you're putting your own firmware in there, you should be able to up the baud rate to 115,200...

- Jon
If you're putting your own firmware in there, you should be able to up the baud rate to 115,200...

- Jon
JonHylands
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 512
Joined: Thu Nov 09, 2006 1:00 am
Location: Ontario, Canada

Post by billyzelsnack » Sun Jan 14, 2007 4:48 am

Post by billyzelsnack
Sun Jan 14, 2007 4:48 am

Cool. Maybe it'll be fast enough to control and get feedback from all the servos using a little bit of simple compression.
Cool. Maybe it'll be fast enough to control and get feedback from all the servos using a little bit of simple compression.
billyzelsnack
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 618
Joined: Sat Dec 30, 2006 1:00 am

Post by billyzelsnack » Sun Jan 14, 2007 7:30 am

Post by billyzelsnack
Sun Jan 14, 2007 7:30 am

I finally got WinAVR working on Vista and made some progress. I now have the AMAZING (haha) ability to move a servo back and forth 10 units with the a/d keys from within the robot terminal. That requires the ability to read the position, then write the position plus a delta. So far so good.

I'm far enough now that I feel like I can abandon the terminal and start using my own software.

I'm wondering how long it will take before I can't stand dealing with the annoying manual bootloader process. I'm thinking that I could just have my software notice if my firmware hex file has changed and upload it if it has. That would be quite convenient.
I finally got WinAVR working on Vista and made some progress. I now have the AMAZING (haha) ability to move a servo back and forth 10 units with the a/d keys from within the robot terminal. That requires the ability to read the position, then write the position plus a delta. So far so good.

I'm far enough now that I feel like I can abandon the terminal and start using my own software.

I'm wondering how long it will take before I can't stand dealing with the annoying manual bootloader process. I'm thinking that I could just have my software notice if my firmware hex file has changed and upload it if it has. That would be quite convenient.
billyzelsnack
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 618
Joined: Sat Dec 30, 2006 1:00 am

Post by billyzelsnack » Mon Jan 15, 2007 12:27 am

Post by billyzelsnack
Mon Jan 15, 2007 12:27 am

I have a little minimal app talking to the servos via my little api now.

I have a couple of options at this point. I can decide on using the Dynamixel packet protocol directly, or make up my own and have the CM5 translate, or maybe do both.

I am thinking that I might go for both and have the ability to mix and match them. The CM5 could distinguish between the two by looking at the first byte in a packet. If it's 0xff it is the Dynamixel protocol. If not it is another protocol.

The nice thing about having my own protocol is that I can compress it before transmission and decompress on the CM5. It mostly would do this by having each side keep track of the known states of the other side and sending only minimal delta information to update each other.
I have a little minimal app talking to the servos via my little api now.

I have a couple of options at this point. I can decide on using the Dynamixel packet protocol directly, or make up my own and have the CM5 translate, or maybe do both.

I am thinking that I might go for both and have the ability to mix and match them. The CM5 could distinguish between the two by looking at the first byte in a packet. If it's 0xff it is the Dynamixel protocol. If not it is another protocol.

The nice thing about having my own protocol is that I can compress it before transmission and decompress on the CM5. It mostly would do this by having each side keep track of the known states of the other side and sending only minimal delta information to update each other.
billyzelsnack
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 618
Joined: Sat Dec 30, 2006 1:00 am

Post by billyzelsnack » Mon Jan 15, 2007 10:11 am

Post by billyzelsnack
Mon Jan 15, 2007 10:11 am

Oh how I love debugging packing/unpacking data with my eyes shut! haha. I really need to get my tools in order. I'm trying to do this thing non-overlap and that gives me only limited print debugging.

I decided on first going the raw route. The CM5 just grabs the packets and forwards them in either direction. I finally got it to set the position of the servo with a servo packet constructed on the C side (instead of just sending keys that the CM5 listens for). I spent a lot of time scratching my head because I assumed that you could just set the low byte for the goal position. Well, apparently not. As soon as I send another 0 for the high byte my servo shot over to the expected position. I'm a little disappointed that it works this way because you can get nearly a 2x compression for free by knowing what side of 'the line' the servo is at.

I'm also wondering if I might be able to make this work in almost the same way with the CM5 or without (with the half-duplex circuit). The WaitCommEvent allows you to know when you've transmitted everything with the EV_TXEMPTY event and after you get that you could set some control flags to change your tx/rx direction. The question is how long the OS and the other hardware between the port and that call will twiddle their thumbs.

btw. Here's what the barebones api is looking like so far..

Code: Select all
int  dmtalk_connect( enum DMTalkVersion apiVersion, const char* port );
void dmtalk_disconnect( );
int  dmtalk_readPacket( int servoId, enum DMTalkReadOp instruction, enum DMTalkAddress address, int readLength, const unsigned char* result_buffer);
int  dmtalk_writePacket( int servoId, enum DMTalkWriteOp instruction, enum DMTalkAddress address, int writeLength, const unsigned char* data);


On top of this I'll build the more pretty and useful functions.
Oh how I love debugging packing/unpacking data with my eyes shut! haha. I really need to get my tools in order. I'm trying to do this thing non-overlap and that gives me only limited print debugging.

I decided on first going the raw route. The CM5 just grabs the packets and forwards them in either direction. I finally got it to set the position of the servo with a servo packet constructed on the C side (instead of just sending keys that the CM5 listens for). I spent a lot of time scratching my head because I assumed that you could just set the low byte for the goal position. Well, apparently not. As soon as I send another 0 for the high byte my servo shot over to the expected position. I'm a little disappointed that it works this way because you can get nearly a 2x compression for free by knowing what side of 'the line' the servo is at.

I'm also wondering if I might be able to make this work in almost the same way with the CM5 or without (with the half-duplex circuit). The WaitCommEvent allows you to know when you've transmitted everything with the EV_TXEMPTY event and after you get that you could set some control flags to change your tx/rx direction. The question is how long the OS and the other hardware between the port and that call will twiddle their thumbs.

btw. Here's what the barebones api is looking like so far..

Code: Select all
int  dmtalk_connect( enum DMTalkVersion apiVersion, const char* port );
void dmtalk_disconnect( );
int  dmtalk_readPacket( int servoId, enum DMTalkReadOp instruction, enum DMTalkAddress address, int readLength, const unsigned char* result_buffer);
int  dmtalk_writePacket( int servoId, enum DMTalkWriteOp instruction, enum DMTalkAddress address, int writeLength, const unsigned char* data);


On top of this I'll build the more pretty and useful functions.
billyzelsnack
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 618
Joined: Sat Dec 30, 2006 1:00 am

Post by billyzelsnack » Tue Jan 16, 2007 8:40 am

Post by billyzelsnack
Tue Jan 16, 2007 8:40 am

I'm now able to get/set servo values, though I have some garbage in there so I have to do it multiple times for it to work. Good thing is that it seems to be robust enough to get itself out of a mess. Now to get rid of the mess!

The API continues to evolve. Here's today incarnation..


int dmtalk_connect( enum DMTalkApiVersion apiVersion, const char* port );
void dmtalk_disconnect( );
int dmtalk_packet_read( int valuesCapacity, unsigned char* result_values );
int dmtalk_packet_write( int servoId, enum DMTalkInstruction instruction, enum DMTalkAddress address, int numValues, const unsigned char* values);
int dmtalk_value_get( int servoId, enum DMTalkAddress address, int numValues, unsigned char* result_values);
int dmtalk_value_get_8( int servoId, enum DMTalkAddress address, unsigned char* result_value);
int dmtalk_value_get_16( int servoId, enum DMTalkAddress address, unsigned short* result_value);
int dmtalk_value_set( int servoId, enum DMTalkAddress address, int dataLength, const unsigned char* data);
int dmtalk_value_set_8( int servoId, enum DMTalkAddress address, unsigned char value);
int dmtalk_value_set_16( int servoId, enum DMTalkAddress address, unsigned short value);
I'm now able to get/set servo values, though I have some garbage in there so I have to do it multiple times for it to work. Good thing is that it seems to be robust enough to get itself out of a mess. Now to get rid of the mess!

The API continues to evolve. Here's today incarnation..


int dmtalk_connect( enum DMTalkApiVersion apiVersion, const char* port );
void dmtalk_disconnect( );
int dmtalk_packet_read( int valuesCapacity, unsigned char* result_values );
int dmtalk_packet_write( int servoId, enum DMTalkInstruction instruction, enum DMTalkAddress address, int numValues, const unsigned char* values);
int dmtalk_value_get( int servoId, enum DMTalkAddress address, int numValues, unsigned char* result_values);
int dmtalk_value_get_8( int servoId, enum DMTalkAddress address, unsigned char* result_value);
int dmtalk_value_get_16( int servoId, enum DMTalkAddress address, unsigned short* result_value);
int dmtalk_value_set( int servoId, enum DMTalkAddress address, int dataLength, const unsigned char* data);
int dmtalk_value_set_8( int servoId, enum DMTalkAddress address, unsigned char value);
int dmtalk_value_set_16( int servoId, enum DMTalkAddress address, unsigned short value);
billyzelsnack
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 618
Joined: Sat Dec 30, 2006 1:00 am

Post by billyzelsnack » Wed Jan 17, 2007 7:45 am

Post by billyzelsnack
Wed Jan 17, 2007 7:45 am

I didn't have much time to work tonight, but I finally put in print mechanism. It will be MUCH easier to debug things now. Nothing like being able to see what you're doing!
I didn't have much time to work tonight, but I finally put in print mechanism. It will be MUCH easier to debug things now. Nothing like being able to see what you're doing!
billyzelsnack
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 618
Joined: Sat Dec 30, 2006 1:00 am

Post by billyzelsnack » Fri Jan 26, 2007 5:55 am

Post by billyzelsnack
Fri Jan 26, 2007 5:55 am

I think I have things pretty much working minus pings. I can't seem to get the timeouts properly configured and it is hanging on me.

Does anyone have experience with what I should set these to? Maybe I should just do it async and be done with it. bah.
I think I have things pretty much working minus pings. I can't seem to get the timeouts properly configured and it is hanging on me.

Does anyone have experience with what I should set these to? Maybe I should just do it async and be done with it. bah.
billyzelsnack
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 618
Joined: Sat Dec 30, 2006 1:00 am

Post by billyzelsnack » Fri Jan 26, 2007 7:58 am

Post by billyzelsnack
Fri Jan 26, 2007 7:58 am

Well I got the pings 'working'. I just don't bother WaitForCommEvent and it appears to work.

I made a little program that lets me record poses and play them back. However, I am getting nearly a 1/2 second delay between hitting a key to set a pose and the pose actually happening.

That's not gonna work!

I'm using the normal humanoid minus 2 servos, so it is a decent amount of servos. I'm guessing the problem is with my read timeouts. Tomorrow I'll make a key that'll toggle the servos replies and see if that helps things.
Well I got the pings 'working'. I just don't bother WaitForCommEvent and it appears to work.

I made a little program that lets me record poses and play them back. However, I am getting nearly a 1/2 second delay between hitting a key to set a pose and the pose actually happening.

That's not gonna work!

I'm using the normal humanoid minus 2 servos, so it is a decent amount of servos. I'm guessing the problem is with my read timeouts. Tomorrow I'll make a key that'll toggle the servos replies and see if that helps things.
billyzelsnack
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 618
Joined: Sat Dec 30, 2006 1:00 am

Post by pepperm » Sat Jan 27, 2007 10:17 am

Post by pepperm
Sat Jan 27, 2007 10:17 am

Hi
What you are doing looks really good and you are clearly making progress.
Interestingly, Limor and I are trying to do something similar or at least
related. We are trying to make a Bioloid I/O module that would sit on the
1Mbit bus and provide extended I/O functionality to the Bioloid. I am
thinking of providing things like extra I/O to control whatever takes your
fancy or allows interfacing to other interface types such as i2C. Maybe the
unit could be used to get input from other sensor types such as a compass,
gyro or sonar unit. Details of the hardware are published here
http://robosavvy.com/modules.php?name=Forums&file=viewtopic&t=572&highlight=bioloid.

So far we have some code that is able to spot data being sent on the bus
but we are making very slow progress getting any further, and I was
wondering if you would be interested in helping out (if you have time that
is of course). Limor has some code in C and I have some in BASCOM AVR that
does the same thing. It just flashes an LED when data is seen on the bus.

What do you think?

Mark
Hi
What you are doing looks really good and you are clearly making progress.
Interestingly, Limor and I are trying to do something similar or at least
related. We are trying to make a Bioloid I/O module that would sit on the
1Mbit bus and provide extended I/O functionality to the Bioloid. I am
thinking of providing things like extra I/O to control whatever takes your
fancy or allows interfacing to other interface types such as i2C. Maybe the
unit could be used to get input from other sensor types such as a compass,
gyro or sonar unit. Details of the hardware are published here
http://robosavvy.com/modules.php?name=Forums&file=viewtopic&t=572&highlight=bioloid.

So far we have some code that is able to spot data being sent on the bus
but we are making very slow progress getting any further, and I was
wondering if you would be interested in helping out (if you have time that
is of course). Limor has some code in C and I have some in BASCOM AVR that
does the same thing. It just flashes an LED when data is seen on the bus.

What do you think?

Mark
pepperm
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 190
Joined: Sat Jul 01, 2006 1:00 am


11 postsPage 1 of 1
11 postsPage 1 of 1