Ergotours via RS232

Hi,

my new project is to communicate about an RS232 port with an Ergometer from Kettler (like an Velosimulators <-- don’t know if this the right word) to Blender’s BGE to simulate some routs for training.

and this Project called “Ergotours”

first I setup some serial python scripts:

that is an modified version from the official py_serial documentation


import serial

#Can be Downloaded from this Link
#https://pypi.python.org/pypi/pyserial

#Function to Initialize the Serial Port
class Ergometer_Com:

    def __init__(self):
        COMNUM = 3          #Enter Your COM Port Number Here.
        self.ser = 0        #Must be declared in Each Function
        self.ser = serial.Serial()
        self.ser.baudrate = 9600
        self.ser.stopbits = serial.STOPBITS_ONE
        self.ser.bytesize = serial.EIGHTBITS
        self.ser.port = COMNUM - 1   #COM Port Name Start from 0
        
        #ser.port = '/dev/ttyUSB0' #If Using Linux

        #Specify the TimeOut in seconds, so that SerialPort
        #Doesn't hangs
        self.ser.timeout = 10
        self.ser.open()          #Opens SerialPort

        # print port open or closed
        if self.ser.isOpen():
            print('Open: ' + self.ser.portstr)
            self.loop()
    #Function Ends Here
            

    #Call the Serial Initilization Function, Main Program Starts from here
    #init_serial()

    def loop(self):
        readin = ''
        while self.ser.isOpen():
            '''if not 'ACK' in readin or not 'RUN' in readin:
                #temp = input('Type what you want to send, hit enter:
')
                self.ser.write(b'CM
')    #Writes to the SerialPort
                print(self.ser.write)       #Writes to the SerialPort
                loopstate = 1'''
            #else:
            self.ser.write(b'ST
')       #Writes to the SerialPort
            print(self.ser.write)       #Writes to the SerialPort
            loopstate = 1

            while loopstate == 1:
                bytes = self.ser.readline()  #Read from Serial Port
                readin = str(bytes)
                print(readin) #Print What is Read from Port
                loopstate = 0

ergometer_com = Ergometer_Com()

def main():
    ergometer_com.loop()
    

that is the final version


#from the_cannibal

from bge import logic
import serial


class Ergometer_Com:

    def __init__(self):
        COMNUM = 3
        self.ser = 0
        self.ser = serial.Serial()
        self.ser.baudrate = 9600
        self.ser.stopbits = serial.STOPBITS_ONE
        self.ser.bytesize = serial.EIGHTBITS
        self.ser.port = COMNUM - 1

        self.ser.timeout = 10

        self.ser.open()

        if self.ser.isOpen():
            print('Open: ' + self.ser.portstr)
            #self.ser.write(b'RS
')
            
            self.ser.write(b'CM
')
            
            cm_recieve = self.ser.readline().decode('ascii').strip()
            print(cm_recieve)
            if "ACK" in cm_recieve:
                print("CM_Setup_OK")
                self.loop()
            elif "RUN" in cm_recieve:
                print("CM_Setup_OK")
                self.loop()
            else:
                print("error to send CM")
                self.loop()
            

    def loop(self):
        
        own = logic.getCurrentController().owner
        obj = logic.getCurrentScene().ojects
        loopstate = 0
        readin = ""
        data_list = []
        
        step_raw = str(own["new_step"])
        
        step_power = str.encode("PW " + step_raw + "
")        

        #print(step_power)
        
        self.pulse = 0
        self.rpm = 0
        self.speed = 0.000
        self.distance = 0.000
        self.power = 0
        self.energy = 0
        self.time = ""
        self.power_actuell = 0

        if loopstate == 0:        
            self.ser.write(b'ST
')
            loopstate = 1

        if loopstate == 1:
            data = self.ser.readline()
            readin = data.decode('ascii').strip()
            data_list = readin.split('	')
            print(data_list)
            
            self.pulse = data_list[0]
            self.rpm = data_list[1]
            self.speed = float(data_list[2])
            self.newspeed = float(self.speed/10)
            self.distance = float(data_list[3])
            self.newdistance = float(self.distance/10)
            self.power = data_list[4]
            self.energy = data_list[5]
            self.time = data_list[6]
            self.power_actuell = data_list[7]

            own["newspeed"] = self.newspeed

            print("pulse: " + str(self.pulse))
            print("rpm: " + str(self.rpm))
            print("speed: " + str(self.newspeed))
            print("distance: " + str(self.newdistance))
            print("power: " + str(self.power))
            print("energy: " + str(self.energy))
            print("time: " + str(self.time))
            print("power_current: " + str(self.power_actuell))

            #self.ser.close()
            loopstate = 2
    
        if loopstate == 2:
            self.ser.write(step_power)
            loopstate = 3

        if loopstate == 3:
            data1 = self.ser.readline()
            readin1 = data.decode('ascii').strip()
            loopstate = 0

    
        obj['HUD_Text_Pulse']['Text'] = self.pulse
        obj['HUD_Text_RPM']['Text'] = self.rpm
        obj['HUD_Text_Speed']['Text'] = own["newspeed"]/10
        obj['HUD_Text_Distance']['Text'] = self.distance
        obj['power_frame_step']['power_frame_step'] = 1*own["new_step"]/80
        print(obj['power_frame_step']['power_frame_step'])
        obj['HUD_Text_Energy']['Text'] = self.energy
        obj['HUD_Text_Time']['Text'] = self.time
    
ergometer_com = Ergometer_Com()

def main():
    ergometer_com.loop()

image from blender will follow soon:D

Attachments


this game/simulation is coming with two languages (German and English)


from bge import logic

def change():
    objlist = logic.getCurrentScene().objects
    
    
    if objlist["Buttons_lang_eng"]["Buttons_lang_eng"] == 0:
        for o in objlist:
            if "language" in o:
                o["language"] = "de"
    else:
        for o in objlist:
            if "language" in o:
                o["language"] = "eng"

so if this project finished I will give it for free away so every one with an Kettler device can use it

Attachments


so some pictures from the menu


and some more info:

the program can manipulate the gear from the Kettler device and if the street or way go up the power from the ergometer will go up too


next time som images from one of the routs you can choice between two at the moment

Attachments



new progress:

features:

  • preview the rout in an short animation how it looks like and will show some interesting points (more power or less)
  • automatic gear (5 watt steps)
  • free routes (for now 2 later 6)
  • language (German or English)
  • HUD for more details (speed, power, rpm, pulse, distance, energy, time)
  • configurable gfx and lod (3 steps: low, middle, high)

so don’t know if I should apply some sound settings, maybe I will open a Poll or something

so some route images from the hill_landscape_start_menu.blend
(not finished)

(side question: Is it possible to post video material?)

Attachments


the intro logo
stc=1

Attachments


I have no idea whats going on - but it looks nice. Keep it going and keep posting!
Thanks.

@mziskandar
I try to intense the training for some kind of Ergometer from Kettler like this (click)
don’t know the right word in English so if you know it please post, thanks

Ergometer (KETTLER FX1) serial protocolwith the help from this web-site I get all commands I need for the serial port protocol THX

load screen is finish

Attachments


the new world is an ice world (not finished)
here you can see some pre-pictures

like the icy material color and normalmap

Attachments



Now I know. Thanks.

prototype from the menu (in_game)<-- not really a game more like an simulation

you can read all your stats from this menu
first steps:

Attachments


some updates about the menu and stats:


Attachments



update:
stats are now working
improve some scripts to get more fps
LOD system in work
gfx settings in work

+add more options get an average power value to get more control over your rout (between 50 to 100 Watt)


that is the (ingame) menu
next time more about the LOD system
have a nice weekend

Attachments


This is pretty cool. Does it work with an exercise machine?

that will be the load_screen (finished version):
load_screen.blend (694 KB)

+++UPDATE+++UPDATE+++UPDATE+++UPDATE+++UPDATE+++UPDATE+++

hi again have really hard worked to present some more cool features:

Version 0.4.4 Alpha build:

-adding, duration: set the session duration and it will end automatically for you if finished
-improve, gfx: low, middle, high ; powerful or beautiful? choose the right for your PC
-adding but not finished, weather: choose between clear and sunny, rain and dark or misty
-adding but not finished, time cycle: choose when the time cycle will start: auto, morning, midday, evening and night or turn it off
-adding but not finished, save your data to tables or diagrams (realised with plotly and html)

reworking the menu, load screen and levels

here are some pictures:

really sorry didn’t get the image uploaded tomorrow I will see what I can do

hi it take while but the image: