You are here

PyVESC - Realtime Data - Experiment Export .csv file

5 posts / 0 new
Last post
Eric_IraLo
Offline
Last seen: 4 months 1 week ago
VESC Free
Joined: 2024-01-29 22:17
Posts: 7
PyVESC - Realtime Data - Experiment Export .csv file

Good morning everyone! 

I hope that you are doing great wherever in the world you might be. 

 

I am new to VESC and I have been trying to create a comparison of different motors that I purchase from Flipsky. I have the model "63100 170KV 5500W" and also the model "7070 110kv". My main goal is to export some recorded data of the motors in the 'Experiment' sub-menu from the 'Data Analysis/Realtime Data' menu. 

 

I have been trying to set up the 'Motor Settings/Experiments Menu' so that I can run the Experiment and hopefully get some data out and export it as a ".csv" file. 

 

I have been looking around everywhere, but I seem to not be able to succesfully get my data collected. If anyone could help me out I would really appreciate it. 

 

Thanks a lot for all the help beforehand.

 

Best wishes,

EIL

Eric_IraLo
Offline
Last seen: 4 months 1 week ago
VESC Free
Joined: 2024-01-29 22:17
Posts: 7

Could someone please help me??

I would really appreciate it, still struggling with the same problem.

Eric Irabien Lozano

electricfox
electricfox's picture
Online
Last seen: 44 sec ago
VESC Original
Joined: 2019-01-01 17:11
Posts: 126

To make sure your RT Data Logging is logged: Edit-> Preferences-> Paths -> RT Data Log. Make sure to select a path.

Eric_IraLo
Offline
Last seen: 4 months 1 week ago
VESC Free
Joined: 2024-01-29 22:17
Posts: 7

Thank you so much for your response!! I appreciate it a lot! 

 

Eric Irabien Lozano

Eric_IraLo
Offline
Last seen: 4 months 1 week ago
VESC Free
Joined: 2024-01-29 22:17
Posts: 7

After getting more and more familiar with the VESC software and also some Python incorporation that can be done with the PyVESC module, I am trying to build a project where I run both of the motors that I purchased previously from Flipsky, "63100 170KV 5500W" & "7070 110kv". 

 

My main goal of the experiment, is that I connected both of them mechanically, and having in between a gearbox on 9:1 (to increase RPM and get more torque), so when one of them spins, the other one does too. But once the 'Driver' motor reaches certain RPM, the 'Generator' Motor starts braking and in this case doing some regenerative-braking to see how much power can be generated. 

 

My issue so far has been that the connection with Python and VESC is not that stable, but also NO-DATA is being logged or stored to be latter exported in a.csv file. 

I am currently trying to build a code in Python, I am attaching what I currently have so far. 

 

In this code, the Driver Motor is able to start, but I do not see the Gen Motor starting to brake in steps. Then when both motors finish, I always get the error that says that the Error is that there ir NO-DATA to be able to be exported as a separate file. I still havent't filtered the data, but my first goal is to just see data being exported somehow.

 

Thank you so much for you help and I am looking forward to maybe start a conversation on how to solve this issue.

 

Thanks again,

Eric Irabien Lozano.

 

 

My most updated code as of today (March, Wednesday 13th, 2024);

# Import necessary libraries

from threading import Thread

import csv

import time

import math

import numpy as np

import matplotlib.pyplot as plt

from pyvesc import VESC

 

# Motor parameters and constants

gearbox_ratio = 9

rolling_radii_TW_IN = 1.25

rolling_radii_eGen_IN = 1.25

experiment_duration = 20

driver_pole_pairs = 7

gen_pole_pairs = 7

ms = 0.01                           #Minimum-Sleep time

 

# Initialize the VESC communication

driverVESC = VESC("COM9", False, True, 115200, ms)   # Replace/Double-check with the correct serial port for your DriverVESC

genVESC  =   VESC("COM16", False, True, 115200, ms)  # Replace/Double-check with the correct serial port for your GenVESC

 

# Collect data for both motors

driver_data = []

gen_data = []

 

target_speed_mph = float(input("Enter the target speed (MPH) for the Driver Motor: "))

 

# Function to calculate the target_speeds_mph into RPMs for DriverVESC

def mph_to_erpm_driverVESC(mph):

   

    #Calculate the circumference (rolling radii * 2π)

    circumference_inches = 2 * math.pi * rolling_radii_TW_IN

 

    #Convert Miles per Hour to inches per minute (1 mile = 63,360 in)

    inches_per_minute = (float(mph) * 63360) / 60  

 

    #Convert to RPM dividing the inches_per_minute by the circumference of the wheel.

    rpm = inches_per_minute / circumference_inches

 

    #Calculate the RPM (ERPM) output of the motor, considering the pole pairs

    erpm = rpm * driver_pole_pairs

 

    return erpm

 

# Function to calculate the MPH from the RPM for DriverVESC

def erpm_to_mph_driverVESC(erpm):

 

    #Calculate the circumference (rolling radii * 2π)

    circumference_inches = 2 * math.pi * rolling_radii_TW_IN

 

    #Calculate the RPM (ERPM) output of the motor, considering the pole pairs

    rpm = erpm / driver_pole_pairs

 

    #Convert RPM to inches per minute taking into acount the circumference of the wheel.

    inches_per_minute = (rpm*circumference_inches)

 

    #Convert to MPH by multipling the inches_per_minute by 60 minutes of an hour over, (1 mile = 63,360 in).

    mph = (float(inches_per_minute) * 60) / 63,360

 

    return mph

 

#Function to calculate the MPH from the eGen Motor

def rpm_to_mph_genVESC(erpm):

   

    #Calculate the circumference (rolling radii * 2π)

    circumference_inches = 2 * math.pi * rolling_radii_eGen_IN

 

    #Calculate the RPM (ERPM) output of the motor, considering the pole pairs

    rpm = erpm / gen_pole_pairs

 

    #Convert RPM to inches per minute taking into acount the circumference of the wheel.

    inches_per_minute = (rpm*circumference_inches)

 

    #Convert to MPH by multipling the inches_per_minute by 60 minutes of an hour over, (1 mile = 63,360 in).

    mph = (float(inches_per_minute) * 60) / 63,360

 

    return mph

 

# Function to control regenerative braking for GenVESC

def regenerative_braking():

    epsilon = 2                 #Small value to account for floating-point comparison, this would check for a difference of less than 2 MPH

    Brake_Current = 6           #The motor should start free-spinning applying no constrain to the set-speed of the driver.

    Brake_Step = 0.2            #How much the Brake will step, or increase, every 5 seconds.

   

    # Start DriverVESC at saved target speeds (MPH)

    if time.time() % 5 == 0 and abs(target_speed_mph - erpm_to_mph_driverVESC(driverVESC.get_rpm())) < epsilon:

        Brake_Current += Brake_Step

        genVESC.set_current(Brake_Current)

        time.sleep(ms)

 

# Stop both motors by setting their current to 0,

def stop_motors():

    print("Stopping both motors.")

    driverVESC.set_current(0)

    genVESC.set_current(0)

 

# Function to collect data from driverVESC

def time_get_values_D():

    start = time.time()

    while time.time() - start < experiment_duration:

        driver_data.append(driverVESC.get_measurements())

        time.sleep(ms)  

    return driver_data

 

# Function to collect data from genVESC

def time_get_values_E():

    start = time.time()

    while time.time() - start < experiment_duration:    

        gen_data.append(genVESC.get_measurements())

        time.sleep(ms)  

    return gen_data

 

# Function to save data to CSV file

def save_to_csv(data, motor_name):

    filename = f"{motor_name.lower()}_data.csv"

    with open(filename, "w", newline="") as csvfile:

        writer = csv.writer(csvfile)

        writer.writerow(["Time (s)", "RPM", "Power (W)", "Amps (A)"])

        writer.writerows(data)

    print(f"Data for {motor_name} saved to {filename}")

 

# Function to plot comparison graphs

def plot_comparison_graphs(driver_data, gen_data):

    driver_data = np.array(driver_data)

    gen_data = np.array(gen_data)

 

    plt.figure(figsize=(10, 6))

 

    plt.subplot(3, 1, 1)

    plt.plot(driver_data[:, 0], driver_data[:, 2], label="DriverVESC")

    plt.plot(gen_data[:, 0], gen_data[:, 2], label="GenVESC")

    plt.xlabel("Time (s)")

    plt.ylabel("Power (W)")

    plt.legend()

 

    plt.subplot(3, 1, 2)

    plt.plot(driver_data[:, 0], driver_data[:, 3], label="DriverVESC")

    plt.plot(gen_data[:, 0], gen_data[:, 3], label="GenVESC")

    plt.xlabel("Time (s)")

    plt.ylabel("Amps (A)")

    plt.legend()

 

    plt.subplot(3, 1, 3)

    plt.plot(driver_data[:, 0], driver_data[:, 1], label="DriverVESC")

    plt.plot(gen_data[:, 0], gen_data[:, 1], label="GenVESC")

    plt.xlabel("Time (s)")

    plt.ylabel("RPM")

    plt.legend()

 

    plt.tight_layout()

    plt.show()

 

# Main function

def main():

    # Start DriverVESC at saved target speed (MPH)

    print(f"Starting DriverVESC at {target_speed_mph} MPH.")

    str_speed = str(mph_to_erpm_driverVESC(target_speed_mph))

 

    #Get the value of the ERPMs and the RPMs.

    erpm_setpoint = math.ceil(float(str_speed))

    rpm_setpoint = erpm_setpoint / driver_pole_pairs

   

    driverVESC.set_rpm(int(erpm_setpoint))

    print(f"Which is translated to: {erpm_setpoint} eRPMs." )

    print(f"Which is also translated to: {rpm_setpoint} RPMs." )

    time.sleep(30)

 

    # Stop motors after completing the experiment

    stop_motors()

 

    # Clean up (close the connection)

    if genVESC.__exit__ and driverVESC.__exit__:

        print("Serials closed")

        VESC.__exit__

        exit()

 

    # Save data to CSV files

    save_to_csv(driver_data, "driverVESC")

    save_to_csv(gen_data, "genVESC")

 

    # Plot comparison graphs

    plot_comparison_graphs(driver_data, gen_data)

 

if __name__ == "__main__":

    Thread(target = main).start()

    Thread(target = time_get_values_D).start()

    Thread(target = time_get_values_E).start()

    Thread(target = regenerative_braking).start()

 

 

Eric Irabien Lozano