BioloidCControl - Alternative firmware for CM-510

Bioloid robot kit from Korean company Robotis; CM5 controller block, AX12 servos..
57 postsPage 4 of 41, 2, 3, 4
57 postsPage 4 of 41, 2, 3, 4

Post by planius » Mon Mar 25, 2013 12:21 am

Post by planius
Mon Mar 25, 2013 12:21 am

Yes, you have to re-flash the original task and motion files after you re-installed the Robotis firmware. BioloidCControl exceeds 64KB and partially overwrites the Task and Motion files.

Did you follow the instructions in the User Guide regarding the installation and operation of BioloidCControl? What output did you see on the serial port?
Yes, you have to re-flash the original task and motion files after you re-installed the Robotis firmware. BioloidCControl exceeds 64KB and partially overwrites the Task and Motion files.

Did you follow the instructions in the User Guide regarding the installation and operation of BioloidCControl? What output did you see on the serial port?
planius offline
Savvy Roboteer
Savvy Roboteer
Posts: 40
Joined: Wed Jul 20, 2011 5:33 am

Post by tachikoma » Mon Mar 25, 2013 12:37 pm

Post by tachikoma
Mon Mar 25, 2013 12:37 pm

Seems the problem with BioloidCControl not working was the fact that I used gtkterm under linux to flash the controller. I tried with the roboplus terminal and all works as expected now.
I could have tried that initially, as the gtkterm flashing actually produced an error which I missed the first time:

Code: Select all
 SYSTEM O.K. (CM510 Boot loader V1.51)
 - ld                     
 Write Address : 00000000
 Ready..Error
 Rewriting:0X001C
 Size:0X0003821B  Checksum:58-0A


One thing I forgot to initially mentioning, when compiling the source I got this message:

Code: Select all
In file included from adc.c:39:
global.h:1: error: stray '\357' in program
global.h:1: error: stray '\273' in program
global.h:1: error: stray '\277' in program
In file included from clock.h:28,
                 from adc.c:41:
global.h:1: error: stray '\357' in program
global.h:1: error: stray '\273' in program
global.h:1: error: stray '\277' in program
make: *** [adc.o] Error 1


so I converted the file to ascii:

Code: Select all
iconv --from-code UTF-8 --to-code US-ASCII -c global.h > global.h.ascii


then this error appeared:

Code: Select all
BioloidCControl.o: In function `__do_copy_data':
/usr/src/crux/BioloidCControl/BioloidCControl.c:304: multiple definition of `__do_copy_data'
/opt/cross/avr/lib/gcc/avr/4.3.3/../../../../avr/lib/avr6/crtm2561.o:../../../../crt1/gcrt1.S:195: first defined here
make: *** [BioloidCControl.elf] Error 1


I read up on the bug description in the comment and the linked thread and wondered if the bug also exists in my toolchain. Before investigating further I did comment out the fix and built without it.
How should the bug manifest in case I'd have it?

Anyway all seems to work when the .hex file gets flashed with roboplus terminal, I'm now trying different options with gtkterm to see if I can get it working as well. Later I will reflash the default firmware as well as motion and task files - is there any way to do that without windows, I have it in a vm now but it is slow as hell due to the limited memory I can assign to it.
Seems the problem with BioloidCControl not working was the fact that I used gtkterm under linux to flash the controller. I tried with the roboplus terminal and all works as expected now.
I could have tried that initially, as the gtkterm flashing actually produced an error which I missed the first time:

Code: Select all
 SYSTEM O.K. (CM510 Boot loader V1.51)
 - ld                     
 Write Address : 00000000
 Ready..Error
 Rewriting:0X001C
 Size:0X0003821B  Checksum:58-0A


One thing I forgot to initially mentioning, when compiling the source I got this message:

Code: Select all
In file included from adc.c:39:
global.h:1: error: stray '\357' in program
global.h:1: error: stray '\273' in program
global.h:1: error: stray '\277' in program
In file included from clock.h:28,
                 from adc.c:41:
global.h:1: error: stray '\357' in program
global.h:1: error: stray '\273' in program
global.h:1: error: stray '\277' in program
make: *** [adc.o] Error 1


so I converted the file to ascii:

Code: Select all
iconv --from-code UTF-8 --to-code US-ASCII -c global.h > global.h.ascii


then this error appeared:

Code: Select all
BioloidCControl.o: In function `__do_copy_data':
/usr/src/crux/BioloidCControl/BioloidCControl.c:304: multiple definition of `__do_copy_data'
/opt/cross/avr/lib/gcc/avr/4.3.3/../../../../avr/lib/avr6/crtm2561.o:../../../../crt1/gcrt1.S:195: first defined here
make: *** [BioloidCControl.elf] Error 1


I read up on the bug description in the comment and the linked thread and wondered if the bug also exists in my toolchain. Before investigating further I did comment out the fix and built without it.
How should the bug manifest in case I'd have it?

Anyway all seems to work when the .hex file gets flashed with roboplus terminal, I'm now trying different options with gtkterm to see if I can get it working as well. Later I will reflash the default firmware as well as motion and task files - is there any way to do that without windows, I have it in a vm now but it is slow as hell due to the limited memory I can assign to it.
tachikoma offline
Robot Builder
Robot Builder
Posts: 8
Joined: Thu Mar 21, 2013 5:09 pm

Post by siempre.aprendiendo » Mon Mar 25, 2013 12:50 pm

Post by siempre.aprendiendo
Mon Mar 25, 2013 12:50 pm

It seems that the problem flashing the controller with Linux (or other tools) is some HEX redundancy codes that should be added to the hex , but generating and uploading a bin file, the software is uploaded to the controller correctly altohough it still shows some errors

With Eclipse, Settings, Post Build-steps, command:
avr-objcopy -R .eeprom -O binary ${BuildArtifactFileName} ${BuildArtifactFileBaseName}.bin
It seems that the problem flashing the controller with Linux (or other tools) is some HEX redundancy codes that should be added to the hex , but generating and uploading a bin file, the software is uploaded to the controller correctly altohough it still shows some errors

With Eclipse, Settings, Post Build-steps, command:
avr-objcopy -R .eeprom -O binary ${BuildArtifactFileName} ${BuildArtifactFileBaseName}.bin
siempre.aprendiendo offline
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 559
Joined: Wed Aug 08, 2007 9:13 pm
Location: Barcelona

Post by tachikoma » Mon Mar 25, 2013 1:07 pm

Post by tachikoma
Mon Mar 25, 2013 1:07 pm

thanks a lot for the hint about uploading as bin file. Works like a charm now :)
I'll included the bin generation in the Makefile:

Code: Select all
PROJECT=BioloidCControl

CC=avr-gcc
OBJCOPY=avr-objcopy

MMCU=atmega2561

SOURCES=adc.c balance.c BioloidCControl.c button.c buzzer.c clock.c dxl_hal.c dynamixel.c led.c motion.c pid.c pose.c serial.c walk.c
OBJS=$(SOURCES:.c=.o)

CFLAGS=-Wall -g -std=gnu99 -lm -Os -DF_CPU=16000000UL -mmcu=$(MMCU) -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums


all: $(PROJECT).hex $(PROJECT).bin


$(PROJECT).bin: $(PROJECT).elf
        $(OBJCOPY) -R .eeprom -O binary $(PROJECT).elf $(PROJECT).bin

$(PROJECT).hex: $(PROJECT).elf
        $(OBJCOPY) -O ihex -Wl,-Map="BioloidCControl.map" -Wl,--start-group -Wl,-lm  -Wl,--end-group $< $(PROJECT).hex

$(PROJECT).elf: $(OBJS)
        $(CC) $(CFLAGS) -o $@ $^


%.o: %.c
        $(CC) $(CFLAGS) -c $< -o $@

clean:
        rm -f $(PROJECT).bin
        rm -f $(PROJECT).hex
        rm -f $(PROJECT).elf
        rm -f $(OBJS)


The .bin file was successfully flashed to cm-510 (error was still reported but after pushing start the BioloidCControl command prompt appeared on in the terminal and I was able to launch commands like sit and stnd).
thanks a lot for the hint about uploading as bin file. Works like a charm now :)
I'll included the bin generation in the Makefile:

Code: Select all
PROJECT=BioloidCControl

CC=avr-gcc
OBJCOPY=avr-objcopy

MMCU=atmega2561

SOURCES=adc.c balance.c BioloidCControl.c button.c buzzer.c clock.c dxl_hal.c dynamixel.c led.c motion.c pid.c pose.c serial.c walk.c
OBJS=$(SOURCES:.c=.o)

CFLAGS=-Wall -g -std=gnu99 -lm -Os -DF_CPU=16000000UL -mmcu=$(MMCU) -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums


all: $(PROJECT).hex $(PROJECT).bin


$(PROJECT).bin: $(PROJECT).elf
        $(OBJCOPY) -R .eeprom -O binary $(PROJECT).elf $(PROJECT).bin

$(PROJECT).hex: $(PROJECT).elf
        $(OBJCOPY) -O ihex -Wl,-Map="BioloidCControl.map" -Wl,--start-group -Wl,-lm  -Wl,--end-group $< $(PROJECT).hex

$(PROJECT).elf: $(OBJS)
        $(CC) $(CFLAGS) -o $@ $^


%.o: %.c
        $(CC) $(CFLAGS) -c $< -o $@

clean:
        rm -f $(PROJECT).bin
        rm -f $(PROJECT).hex
        rm -f $(PROJECT).elf
        rm -f $(OBJS)


The .bin file was successfully flashed to cm-510 (error was still reported but after pushing start the BioloidCControl command prompt appeared on in the terminal and I was able to launch commands like sit and stnd).
tachikoma offline
Robot Builder
Robot Builder
Posts: 8
Joined: Thu Mar 21, 2013 5:09 pm

Post by tachikoma » Mon Mar 25, 2013 4:27 pm

Post by tachikoma
Mon Mar 25, 2013 4:27 pm

Jfyi, restored firmware again without errors, uploaded the Bioloid premium model A task file (with Robotask) and uploaded the corresponding motion file (using Robomotion), both according to the instructions in the e-manual. No luck - once selecting Remote mode, it tried to move again into a totally impossible pose.
Interestingly, when selecting the graphical pose editor in Robomotion, in the "step" view all looks right, but when selecting "robot" it showed the wrong pose the robot wanted to move into. As I'm not yet familiar with the Robo* tools from Robotis itself I expect doing something wrong, however - all I did was following the instructions. I'm aware this is not the right thread for it, I just mention it as it occurred after flashing BioloidCCdontrol and there might be a connection.
In case it has something to do with the size of the BioloidCControl firmware, mine have these sizes:

80K BioloidCControl.bin
228K BioloidCControl.hex

Anyway, with BioloidCControl via serial cable connection all works as expected so I wanted to try out using the RC-110 remote control. I therefor edited serial.h and changed it to this:

Code: Select all
// #define SERIAL_CABLE
// #define ZIG_2_SERIAL
#define RC100


I compiled and flashed the new BioloidCControl.bin. After turning it on, the firmware started as expected, I could not enter commands and thus tried using the remote control. This however did not produce any output on the serial console nor any movement of the robot.
Do I have to configure something else in the code - I saw no ir device configured under
ADC Channel settings in global.h?

Last but not least I have another completely unrelated question - the mentioned accelerometer which is used for balance - where would I get that? I googled and found several ones but it seems there is none specific Bioloid version, or did I just not find it.
Jfyi, restored firmware again without errors, uploaded the Bioloid premium model A task file (with Robotask) and uploaded the corresponding motion file (using Robomotion), both according to the instructions in the e-manual. No luck - once selecting Remote mode, it tried to move again into a totally impossible pose.
Interestingly, when selecting the graphical pose editor in Robomotion, in the "step" view all looks right, but when selecting "robot" it showed the wrong pose the robot wanted to move into. As I'm not yet familiar with the Robo* tools from Robotis itself I expect doing something wrong, however - all I did was following the instructions. I'm aware this is not the right thread for it, I just mention it as it occurred after flashing BioloidCCdontrol and there might be a connection.
In case it has something to do with the size of the BioloidCControl firmware, mine have these sizes:

80K BioloidCControl.bin
228K BioloidCControl.hex

Anyway, with BioloidCControl via serial cable connection all works as expected so I wanted to try out using the RC-110 remote control. I therefor edited serial.h and changed it to this:

Code: Select all
// #define SERIAL_CABLE
// #define ZIG_2_SERIAL
#define RC100


I compiled and flashed the new BioloidCControl.bin. After turning it on, the firmware started as expected, I could not enter commands and thus tried using the remote control. This however did not produce any output on the serial console nor any movement of the robot.
Do I have to configure something else in the code - I saw no ir device configured under
ADC Channel settings in global.h?

Last but not least I have another completely unrelated question - the mentioned accelerometer which is used for balance - where would I get that? I googled and found several ones but it seems there is none specific Bioloid version, or did I just not find it.
tachikoma offline
Robot Builder
Robot Builder
Posts: 8
Joined: Thu Mar 21, 2013 5:09 pm

Post by siempre.aprendiendo » Mon Mar 25, 2013 4:57 pm

Post by siempre.aprendiendo
Mon Mar 25, 2013 4:57 pm

Sometimes very strange things ocur, due a a bad cable connection (check ALL of them), low level battery, wrong switch position (USB2Dynamixel), serial connection and Zig or IR connected, two usb2dynamixel connected, ... but IMHO is very very unlikely that the cause could be the previous downloaded firmware.

Have you tried with only one AX-12 connected? serial and usb2dynamixel connection?
Sometimes very strange things ocur, due a a bad cable connection (check ALL of them), low level battery, wrong switch position (USB2Dynamixel), serial connection and Zig or IR connected, two usb2dynamixel connected, ... but IMHO is very very unlikely that the cause could be the previous downloaded firmware.

Have you tried with only one AX-12 connected? serial and usb2dynamixel connection?
siempre.aprendiendo offline
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 559
Joined: Wed Aug 08, 2007 9:13 pm
Location: Barcelona

Post by tachikoma » Mon Mar 25, 2013 6:45 pm

Post by tachikoma
Mon Mar 25, 2013 6:45 pm

I have not tried with only one dynamixel connected, will do that tonight. Everything with the stock firmware worked exactly as documented before I flashed BioloidCControl and did repeatedly show the wrong behavior after reflashing the originalfirmware. Also with BioloidCControl all movements are absolutely fine and as expected, which led me to assume that there is no hardware/connection problem but i definatley will check once more. What I did check was with Robomanager, I e.g zeroed all servos in the manager and the real servos moved to the correct position. Also, in managed mode, all servos move to the correct 0 position and it does go in the correct default standing position with the default firmware. But I'll recheck everything later tonight to make sure that there is not a problem on the robot side.
I have not tried with only one dynamixel connected, will do that tonight. Everything with the stock firmware worked exactly as documented before I flashed BioloidCControl and did repeatedly show the wrong behavior after reflashing the originalfirmware. Also with BioloidCControl all movements are absolutely fine and as expected, which led me to assume that there is no hardware/connection problem but i definatley will check once more. What I did check was with Robomanager, I e.g zeroed all servos in the manager and the real servos moved to the correct position. Also, in managed mode, all servos move to the correct 0 position and it does go in the correct default standing position with the default firmware. But I'll recheck everything later tonight to make sure that there is not a problem on the robot side.
tachikoma offline
Robot Builder
Robot Builder
Posts: 8
Joined: Thu Mar 21, 2013 5:09 pm

Post by planius » Tue Mar 26, 2013 5:25 am

Post by planius
Tue Mar 26, 2013 5:25 am

I will try and go through your issues in order.

1. The error you get in linking '__do_copy_data'. If you need the fix with your toolchain you will notice as the robot will just become unresponsive to commands after a while or not even start. In essence the fix allows access to the part of the code/PROGMEM that extends beyond 64KB.

2. The RC-100 mode with BioloidCControl only works via ZigBee (not IR). If you are using the ZigBee module in the RC-100 and the matching one on the robot, it should work. You should still get output on the serial console if you keep the cable connected to the serial port.

3. The accelerometer I am using (ADXL203) is no longer available. You need a 5V analog accelerometer or a 3.3V analog output accelerometer and a voltage divider (5V -> 3.3V) as the CM-510 supplies 5V. Both can be found at www.sparkfun.com

4. I will try to restore the Robotis firmware on my CM-510 and let you know how it goes. I have done it many times before without any issues, but not since going from version 0.5 to 0.7.
I will try and go through your issues in order.

1. The error you get in linking '__do_copy_data'. If you need the fix with your toolchain you will notice as the robot will just become unresponsive to commands after a while or not even start. In essence the fix allows access to the part of the code/PROGMEM that extends beyond 64KB.

2. The RC-100 mode with BioloidCControl only works via ZigBee (not IR). If you are using the ZigBee module in the RC-100 and the matching one on the robot, it should work. You should still get output on the serial console if you keep the cable connected to the serial port.

3. The accelerometer I am using (ADXL203) is no longer available. You need a 5V analog accelerometer or a 3.3V analog output accelerometer and a voltage divider (5V -> 3.3V) as the CM-510 supplies 5V. Both can be found at www.sparkfun.com

4. I will try to restore the Robotis firmware on my CM-510 and let you know how it goes. I have done it many times before without any issues, but not since going from version 0.5 to 0.7.
Last edited by planius on Tue Mar 26, 2013 9:33 am, edited 1 time in total.
planius offline
Savvy Roboteer
Savvy Roboteer
Posts: 40
Joined: Wed Jul 20, 2011 5:33 am

Post by planius » Tue Mar 26, 2013 8:40 am

Post by planius
Tue Mar 26, 2013 8:40 am

OK, have now re-flashed the original firmware and it all works fine (using default Task and Motion files and RC-100).

Make sure that:
1. Dynamixels are recognised correctly after you flash the Robotis firmware

2. In RoboPlus Motion you upload the default Motion file, not the one it reads back from the controller. After you connect to the robot (F5), it will read the current 'motion' file from the CM-510 (which is partially garbage) and open a CM-510 tab to show this. Then open the default motion file and download it to the robot. If you open the default motion file first, it will switch to the CM-510 tab after connecting.

3. Download the Task file last.

Everything then works exactly as it should with my Type A robot.
OK, have now re-flashed the original firmware and it all works fine (using default Task and Motion files and RC-100).

Make sure that:
1. Dynamixels are recognised correctly after you flash the Robotis firmware

2. In RoboPlus Motion you upload the default Motion file, not the one it reads back from the controller. After you connect to the robot (F5), it will read the current 'motion' file from the CM-510 (which is partially garbage) and open a CM-510 tab to show this. Then open the default motion file and download it to the robot. If you open the default motion file first, it will switch to the CM-510 tab after connecting.

3. Download the Task file last.

Everything then works exactly as it should with my Type A robot.
planius offline
Savvy Roboteer
Savvy Roboteer
Posts: 40
Joined: Wed Jul 20, 2011 5:33 am

Post by tachikoma » Fri Mar 29, 2013 8:31 pm

Post by tachikoma
Fri Mar 29, 2013 8:31 pm

Thanks for all the help and the attempt to reproduce the problem. I now have completely disassembled and reassembled, still the same - works fine with BioloidCControl, but not with the Robotis firmware/taskfile/motionfile


planius wrote:OK, have now re-flashed the original firmware and it all works fine (using default Task and Motion files and RC-100).

Make sure that:
1. Dynamixels are recognised correctly after you flash the Robotis firmware

all were correctly recognised and moved to the correct default positions.

2. In RoboPlus Motion you upload the default Motion file, not the one it reads back from the controller. After you connect to the robot (F5), it will read the current 'motion' file from the CM-510 (which is partially garbage) and open a CM-510 tab to show this. Then open the default motion file and download it to the robot. If you open the default motion file first, it will switch to the CM-510 tab after connecting.

I did it exactly that way and checked if on the robot side the same values were displayed as from the motion file.

3. Download the Task file last.

Worked fine as well.

Everything then works exactly as it should with my Type A robot.


I have tried that now several times, always the same disappointing result :(
As the default pose after turning it on and selecting 'play' does work I assume that the task file is not the problem and was playing around with robomotion some more. And I found that when starting the tool to set the dynamixel offsets I get a 'critical error' from the robomotion software, asking me to restart the robomotion application. It however does not crash and shows a popup window with offset values for the servos. And it contains very weird values, up to -6000 for some servos. I can not change those values however, and wonder if those offset values are the reason for the completely wrong poses of the robot. I'll have to search some more on that, but beside that I have no clue what could cause the issue.

Anyway, I'll tonight will install zigbee to the remote controller and then play some more with BioloidCControl :) Thanks again for that and for all the help and replies.
Thanks for all the help and the attempt to reproduce the problem. I now have completely disassembled and reassembled, still the same - works fine with BioloidCControl, but not with the Robotis firmware/taskfile/motionfile


planius wrote:OK, have now re-flashed the original firmware and it all works fine (using default Task and Motion files and RC-100).

Make sure that:
1. Dynamixels are recognised correctly after you flash the Robotis firmware

all were correctly recognised and moved to the correct default positions.

2. In RoboPlus Motion you upload the default Motion file, not the one it reads back from the controller. After you connect to the robot (F5), it will read the current 'motion' file from the CM-510 (which is partially garbage) and open a CM-510 tab to show this. Then open the default motion file and download it to the robot. If you open the default motion file first, it will switch to the CM-510 tab after connecting.

I did it exactly that way and checked if on the robot side the same values were displayed as from the motion file.

3. Download the Task file last.

Worked fine as well.

Everything then works exactly as it should with my Type A robot.


I have tried that now several times, always the same disappointing result :(
As the default pose after turning it on and selecting 'play' does work I assume that the task file is not the problem and was playing around with robomotion some more. And I found that when starting the tool to set the dynamixel offsets I get a 'critical error' from the robomotion software, asking me to restart the robomotion application. It however does not crash and shows a popup window with offset values for the servos. And it contains very weird values, up to -6000 for some servos. I can not change those values however, and wonder if those offset values are the reason for the completely wrong poses of the robot. I'll have to search some more on that, but beside that I have no clue what could cause the issue.

Anyway, I'll tonight will install zigbee to the remote controller and then play some more with BioloidCControl :) Thanks again for that and for all the help and replies.
tachikoma offline
Robot Builder
Robot Builder
Posts: 8
Joined: Thu Mar 21, 2013 5:09 pm

Post by planius » Fri Mar 29, 2013 11:00 pm

Post by planius
Fri Mar 29, 2013 11:00 pm

Sounds like the problem is connected to the joint offsets, that should be easy to fix/test. Joint Offsets are not stored in the motion file, they live in a separate memory area and (if I recall correctly) that area gets overwritten by BioloidCControl.

So simply add code right at the beginning of the task file where you set all joint offsets to 0 and see if that fixes it. If you are unsure how to do that, please see here:
http://support.robotis.com/en/software/roboplus/roboplus_task/programming/parameter/motion/roboplus_task_jointoffset.htm
Sounds like the problem is connected to the joint offsets, that should be easy to fix/test. Joint Offsets are not stored in the motion file, they live in a separate memory area and (if I recall correctly) that area gets overwritten by BioloidCControl.

So simply add code right at the beginning of the task file where you set all joint offsets to 0 and see if that fixes it. If you are unsure how to do that, please see here:
http://support.robotis.com/en/software/roboplus/roboplus_task/programming/parameter/motion/roboplus_task_jointoffset.htm
planius offline
Savvy Roboteer
Savvy Roboteer
Posts: 40
Joined: Wed Jul 20, 2011 5:33 am

Post by tachikoma » Thu May 02, 2013 5:57 pm

Post by tachikoma
Thu May 02, 2013 5:57 pm

sorry for not replying, was kinda busy ... So I tried resetting the code as described in the documentation, with no success. In the end I decided to go on and do something else, which included disassembly of the robot and building a more simple version. I now built the probing robot and wrote the firmware there myself, imitating the behavior of the taskfile for the original firmware. Reading the BioloidCControl code helped a lot with that :)

There is a video of a short demonstration:
https://www.youtube.com/watch?v=INeR8YlJ7vA

And yes - it's basically just a compilation of code samples form the documentation ;)
sorry for not replying, was kinda busy ... So I tried resetting the code as described in the documentation, with no success. In the end I decided to go on and do something else, which included disassembly of the robot and building a more simple version. I now built the probing robot and wrote the firmware there myself, imitating the behavior of the taskfile for the original firmware. Reading the BioloidCControl code helped a lot with that :)

There is a video of a short demonstration:
https://www.youtube.com/watch?v=INeR8YlJ7vA

And yes - it's basically just a compilation of code samples form the documentation ;)
tachikoma offline
Robot Builder
Robot Builder
Posts: 8
Joined: Thu Mar 21, 2013 5:09 pm

Previous
Previous
57 postsPage 4 of 41, 2, 3, 4
57 postsPage 4 of 41, 2, 3, 4