Python -Script - Создать квадратные промежуточные значения - PullRequest
1 голос
/ 29 мая 2020

Я создаю промежуточные линейные значения с помощью сценария Python, например:

ввод:

000000,0,0,0,0,0
000100,20,90,0,0
016100,20,90,0,0
020100,90,20,0,0
024100,20.90,0.0
028100,90,20,0,0
030 100.0.0.0.0

после сценария я получаю вывод:

RCOU, 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0
RCOU, 100000,1200,1900,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 200000,1200,1900,1000,1000,0,0,0,0,0,0,0,0,0,0,0
.................................................. ..........................................
RCOU, 16100000,1200,1900,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 16200000,1218,1882,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 16300000.1235.1865.1000.1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 16400000,1252,1848,1000,1000,0,0,0,0,0,0,0,0,0,0,0
.................................................. ..........................................
RCOU, 28600000,1675,1150,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 28700000,1630,1140,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 28800000.1585.11130.1000.1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 28900000,1540,1120,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 29000000,1495,1110,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 29100000.1450.1100.1000.1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 29200000,1405,1090,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 29300000.1360.1080.1000.1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 29400000,1315,1070,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 29500000,1270,1060,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 29600000,1225,1050,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 29700000,1180,1040,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 29800000,1135,1030,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 29900000,1090,1020,1000,1000,0,0,0,0,0,0,0,0,0,0,0
RCOU, 30000000,1045,1010,1000,1000,0,0,0,0,0,0,0,0,0,0,0

Is an output picture from python-script, will be used later, for a drone controller

т.е. 3-й б 4-й столбец go линейное увеличение и уменьшение с 1200 до 1900

Однако я хотел бы создать функцию, изменяющуюся - между входные значения - квадрат или sin / cos, а не линейные. На схеме - треугольники заменить на синус.

#!/usr/bin/env python3

from optparse import OptionParser
from sys import argv
import os
from random import randint


def read(file_name):
    b = []
    with open(file_name) as input_file:
        for line in input_file.readlines():
            parts = line.strip().split(',')

            b.append(
                {
                    't': int(parts[0]),
                    'm1': int(parts[1]),
                    'm2': int(parts[2]),
                    'm3': int(parts[3]),
                    'm4': int(parts[4])
                }
            )
    return b


def handle_args():
    parser = OptionParser()
    parser.add_option('-i', '--input', dest='input', help='Input config file that will be read from')
    parser.add_option('-o', '--output', dest='output', help='Output config file that will be written to')
    (opts, args) = parser.parse_args()
    if not opts.input:
        parser.error('Input file not given. {0} -h for help'.format(argv[0]))
        parser.print_help()

    if not opts.output:
        parser.error('Output file not given. {0} -h for help'.format(argv[0]))
        parser.print_help()

    return opts


def write_line(values):
    """
    write a csv line in output file, out of a values dict
    :param values: dict with the data (as declared in read()
    :return: None
    """
    with open(OUTPUT_FILE_NAME, 'a') as out:

        out.write('RCOU,')
        out.write(str(values['t']*1000) +',')

        for _m in motors:
            out.write(str(round(values[_m])) + ',')
        out.write('0,0,0,0,0,0,0,0,0,0')
        out.write('\n')


if __name__ == '__main__':
    options = handle_args()  # handle arguments givenk

    step_size = 100  # ms
    motors = ('m1', 'm2', 'm3', 'm4')  # the motors. Only as field accessors
    OUTPUT_FILE_NAME = options.output  # the output file to write data to. (given in the args)
    INPUT_FILE_NAME = options.input  # the output file to read data from. (given in the args)

    print('reading from', INPUT_FILE_NAME)
    print('writing to', OUTPUT_FILE_NAME)

    blocks = read(options.input)  # read all lines

    # delete file if already exists
    if os.path.exists(OUTPUT_FILE_NAME):
        os.remove(OUTPUT_FILE_NAME)

    # if more than one line in file
    if len(blocks) > 1:

        with open(OUTPUT_FILE_NAME, 'a') as out:

            out.write('samp_rate=44100\nchannel=1\nsamp_size=16\ncodec=Audio/PCM\nbyte_order=QAudioFormat::LittleEndian\nsample_type=QAudioFormat::SignedInt\n')
            # out.write('channel=1\n')
            # out.write('samp_size=16\n')
            # out.write('codec=Audio/PCM\n')
            # out.write('byte_order=QAudioFormat::LittleEndian\n')
            # out.write('sample_type=QAudioFormat::SignedInt\n')
            # out.write('\n')

        write_line(blocks[0])  # write the first line of the input file directly to the output file !!!+1000

        for i in range(0, len(blocks) - 1):  # for every line except the last one
            block = blocks[i]  # the current values
            next_block = blocks[i + 1]  # the next values

            # calculate the step based on the current and next time value and the step_size
            steps_count = int((next_block['t'] - block['t']) / step_size)
            motors_steps = {}

            # get data of the motor fields
            for m in motors:
                # calculate the step of every motor based on the time value
                motors_steps[m] = float((next_block[m] - block[m]) / steps_count)

            for s in range(1, steps_count + 1):
                data = {'t': block['t'] + (step_size * s)}  # get every interim step for time

                for m in motors:
                # data[m] = randint(1250,1500) # get every step random value for every motor
                data[m] = (block[m] + (motors_steps[m] * s)) * 10 + 1000  # get every interim step for every motor
                # push data to file
                write_line(data)

        with open(OUTPUT_FILE_NAME, 'a') as out:
            out.write('RCOU,10100000,56797,56797,56797,56797,0,0,0,0,0,0,0,0,0,0')
    else:
        print('not enough data...')

Думаю, мне нужно изменить эту строку?

data[m] = (block[m] + (motors_steps[m] * s)) * 10 + 1000  # get every interim step for every motor

Ответы [ 3 ]

0 голосов
/ 30 мая 2020

Выглядит лучше, но смещение все еще немного enter image description here

enter image description here

Синус должен начинаться с 16 с, а не Сначала 16,6 с

for m in motors:
     if 0 < motors_diff[m]:
          data[m] = (block[m] + (motors_steps[m] * (s/2) * (1-cos((pi*s)/(steps_count+1)))))   # rise                        
     if 0 > motors_diff[m]:
          data[m] = (block[m] + (motors_steps[m] * (s/2) * (1-cos((pi*s)/(steps_count+1)))))
     if 0 == motors_diff[m]:
          data[m] = (block[m] + (motors_steps[m] * s))  #equals                    
# push data to file 
write_line(data)

Есть идеи?

0 голосов
/ 31 мая 2020

Последнее состояние: for s in range (1, steps_count): data = {'t': block ['t'] + (step_size * s)} # получить каждый промежуточный шаг за время

            for m in motors:
                if 0 != motors_diff[m]:
                    data[m] = (block[m] + (motors_steps[m] * (s/2) * (1-cos((pi*s)/(steps_count)))))   # rise/fall
                if 0 == motors_diff[m]:
                    data[m] = (block[m] + (motors_steps[m] * s))  #equals
            # push data to file 
            write_line(data)

Результат: enter image description here

Нехорошо Пазуха действительно хорошая пазуха. Но лучшее из того, что я могу сделать.

0 голосов
/ 30 мая 2020

Итак, я создаю операторы if:

for m in motors:
     if 0 < motors_diff[m]:
             data[m] = (block[m] + (motors_steps[m] * (s/2) * (1+sin(((pi*s)/(steps_count + 1))-((pi)/2))))) * 10 + 1000  # rise
     if 0 > motors_diff[m]:
             data[m] = (block[m] + (motors_steps[m] * s)) * 10 + 1000 #equals DEBUG
             #data[m] = (block[m] + (motors_steps[m] * (s/2) * (1+sin(((pi*s)/(steps_count + 1))-(pi)/2)))) * 10 + 1000  # rise
     if 0 == motors_diff[m]:
             data[m] = (block[m] + (motors_steps[m] * s)) * 10 + 1000 #equals
             # push data to file 
 write_line(data)

, но получаю значения только между -pi / 2 и 0, а не между -pi / 2 и + pi / 2

enter image description here

Понимаете, может быть, что не так?

Я оставил второй if-оператор без изменений, чтобы увидеть сравнение до и сейчас. Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...