Skip to content

Commit

Permalink
add anticogging support
Browse files Browse the repository at this point in the history
  • Loading branch information
dukelec committed Jul 15, 2024
1 parent ede994d commit 98079b7
Show file tree
Hide file tree
Showing 8 changed files with 336 additions and 2 deletions.
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@
path = mdrv_fw/cdnet
url = ../cdnet

[submodule "pycdnet"]
path = tools/pycdnet
url = ../pycdnet

2 changes: 1 addition & 1 deletion mdrv_fw/STM32G431CBUx_FLASH.ld
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ _Min_Stack_Size = 0x400; /* required amount of stack */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
FLASH (rx) : ORIGIN = 0x8006000, LENGTH = 102K /* 128 - 24 - 2 = 102 */
FLASH (rx) : ORIGIN = 0x8006000, LENGTH = 86K /* 128 -24 (bl) -2 (config) -8 (encoder cali) -8 (anticogging cali) = 86 */
}

/* Define output sections */
Expand Down
16 changes: 15 additions & 1 deletion mdrv_fw/usr/app_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
#define P_3F(x) (int)(x), abs(((x)-(int)(x))*1000) // "%d.%.3d"


#define CALI_ENCODER_TBL 0x0801b800 // 8k, 2bytes x 4096
#define ANTICOGGING_TBL 0x0801d800 // 8k, 2bytes x 4096
#define APP_CONF_ADDR 0x0801f800 // page 63, the last page
#define APP_CONF_VER 0x0105
#define APP_CONF_VER 0x0106

#define CURRENT_LOOP_FREQ (170000000 / 4096 / 2)
#define DRV_PWM_HALF 2048
Expand Down Expand Up @@ -105,6 +107,12 @@ typedef struct {
float cali_angle_step; // increase cali_angle_elec
bool cali_run;

bool cali_encoder_en;
bool anticogging_en;
float anticogging_max_val[2];

uint8_t _reserved[28];

// end of flash
#define _end_save state

Expand Down Expand Up @@ -144,6 +152,12 @@ typedef struct {
int16_t dbg_u;
int16_t dbg_v;

float sen_i_sq_avg;
float cal_v_sq_avg;
uint8_t _reserved2[8];
float sen_speed_avg;
float sen_rpm_avg;

} csa_t; // config status area


Expand Down
17 changes: 17 additions & 0 deletions mdrv_fw/usr/app_motor.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@ static inline void speed_loop_compute(void)

csa.sen_speed = s_avg / 5.0f;
s_avg = 0;
csa.sen_speed_avg += (csa.sen_speed - csa.sen_speed_avg) * 0.005f;
csa.sen_rpm_avg = csa.sen_speed_avg / 0x10000 * 60;

if (csa.state < ST_SPEED) {
pid_f_reset(&csa.pid_speed, 0, 0);
Expand Down Expand Up @@ -451,6 +453,13 @@ void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
csa.sen_i_sq = -i_alpha * sin_tmp_angle_elec + i_beta * cos_tmp_angle_elec;
csa.sen_i_sd = i_alpha * cos_tmp_angle_elec + i_beta * sin_tmp_angle_elec;

if (csa.anticogging_en) {
int8_t *p = (int8_t *)ANTICOGGING_TBL + (csa.sen_encoder >> 4) * 2;
csa.sen_i_sq -= csa.anticogging_max_val[0] * (*p) / 100.0f;
}
float err_i_sq = csa.sen_i_sq - csa.sen_i_sq_avg;
csa.sen_i_sq_avg += err_i_sq * 0.001f;

if (dbg_str)
//d_debug_c(", i %5d %5d %5d", ia, ib, ic);
d_debug_c(", i %5d %5d", adc1_val, adc2_val);
Expand Down Expand Up @@ -478,6 +487,14 @@ void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
#endif
csa.cal_v_sq = pid_f_compute_no_d(&csa.pid_i_sq, csa.sen_i_sq);
csa.cal_v_sd = pid_f_compute_no_d(&csa.pid_i_sd, csa.sen_i_sd); // target default 0

if (csa.anticogging_en) {
int8_t *p = (int8_t *)ANTICOGGING_TBL + (csa.sen_encoder >> 4) * 2;
csa.cal_v_sq += csa.anticogging_max_val[1] * (*(p+1)) / 100.0f;
}
float err_v_sq = csa.cal_v_sq - csa.cal_v_sq_avg;
csa.cal_v_sq_avg += err_v_sq * 0.001f;

if (csa.state == ST_CALI)
csa.cal_v_sd = 0;

Expand Down
12 changes: 12 additions & 0 deletions mdrv_fw/usr/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ int flash_write(uint32_t addr, uint32_t len, const uint8_t *buf)
uint8_t *: "[B]", \
int16_t *: "[h]", \
uint32_t *: "[I]", \
float *: "[f]", \
regr_t: "H,H", \
regr_t *: "{H,H}", \
default: "-"))
Expand Down Expand Up @@ -323,6 +324,11 @@ void csa_list_show(void)
CSA_SHOW(0, cali_run, "0: stopped, write 1 start calibration");
d_info("\n"); debug_flush(true);

CSA_SHOW(0, cali_encoder_en, "");
CSA_SHOW(0, anticogging_en, "");
CSA_SHOW(0, anticogging_max_val, "");
d_info("\n"); debug_flush(true);

CSA_SHOW(0, state, "0: stop, 1: calibrate, 2: cur loop, 3: speed loop, 4: pos loop, 5: t_curve");
//CSA_SHOW(0, err_flag, "not used");
d_info("\n"); debug_flush(true);
Expand Down Expand Up @@ -364,5 +370,11 @@ void csa_list_show(void)
CSA_SHOW(0, dbg_v, "");
d_info("\n"); debug_flush(true);

CSA_SHOW(0, sen_i_sq_avg, "");
CSA_SHOW(0, cal_v_sq_avg, "");
CSA_SHOW(0, sen_speed_avg, "");
CSA_SHOW(0, sen_rpm_avg, "");
d_info("\n"); debug_flush(true);

d_info("\x1b[92mColor Test...\x1b[0m\n");
}
230 changes: 230 additions & 0 deletions tools/anticogging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
#!/usr/bin/env python3
# Software License Agreement (MIT License)
#
# Copyright (c) 2024, DUKELEC, Inc.
# All rights reserved.
#
# Author: Duke Fong <[email protected]>

"""CDFOC anticogging tool
Args:
--dev DEV # specify serial port, default: /dev/ttyACM0
--baud BAUD # set baudrate, default: 115200
--target-addr ADDR # default: 80:00:fe
--help | -h # this help message
--verbose | -v # debug level: verbose
--debug | -d # debug level: debug
--info | -i # debug level: info
Command prompt example:
$ ./anticogging.py
"""

R_tc_pos = 0x01f8
R_anticogging_en = 0x021a
R_anticogging_max_val = 0x021c
R_state = 0x0240
R_tc_state = 0x0284
R_sen_i_sq_avg = 0x029c
R_cal_v_sq_avg = 0x02a0

ANTICOGGING_TBL = 0x0801d800 # 8k, 2bytes x 4096


import sys, os
import struct
import _thread
import re
import json
from time import sleep
from argparse import ArgumentParser
from pathlib import Path

sys.path.append(os.path.join(os.path.dirname(__file__), './pycdnet'))

from cdnet.utils.log import *
from cdnet.utils.cd_args import CdArgs
from cdnet.dev.cdbus_serial import CDBusSerial
from cdnet.dispatch import *

args = CdArgs()
local_mac = int(args.get("--local-mac", dft="0x00"), 0)
dev_str = args.get("--dev", dft="ttyACM0")
baud = int(args.get("--baud", dft="115200"), 0)
target_addr = args.get("--target-addr", dft="80:00:fe")

out_file = args.get("--out-file")
reboot_flag = args.get("--reboot") != None

sub_size = 128

if args.get("--help", "-h") != None:
print(__doc__)
exit()


if args.get("--verbose", "-v") != None:
logger_init(logging.VERBOSE)
elif args.get("--debug", "-d") != None:
logger_init(logging.DEBUG)
elif args.get("--info", "-i") != None:
logger_init(logging.INFO)


dev = CDBusSerial(dev_str, baud=baud)
CDNetIntf(dev, mac=local_mac)
sock = CDNetSocket(('', 0xcdcd))
sock_dbg = CDNetSocket(('', 9))


def dbg_echo():
while True:
rx = sock_dbg.recvfrom()
#print('\x1b[0;37m ' + re.sub(br'[^\x20-\x7e]',br'.', rx[0][5:-1]).decode() + '\x1b[0m')
print('\x1b[0;37m ' + re.sub(br'[^\x20-\x7e]',br'.', rx[0]).decode() + '\x1b[0m')

_thread.start_new_thread(dbg_echo, ())


def csa_write(offset, dat):
sock.sendto(b'\x20' + struct.pack("<H", offset) + dat, (target_addr, 5))
ret, _ = sock.recvfrom(timeout=1)
if ret == None or ret[0] != 0x80:
print(f'csa_write error at: 0x{offset:x}: {dat.hex()}')
return ret

def csa_read(offset, len_):
sock.sendto(b'\x00' + struct.pack("<HB", offset, len_), (target_addr, 5))
ret, _ = sock.recvfrom(timeout=1)
if ret == None or ret[0] != 0x80:
print(f'csa_write read at: 0x{offset:x}, len: {len_}')
return ret


def _read_flash(addr, _len):
sock.sendto(b'\x00' + struct.pack("<IB", addr, _len), (target_addr, 8))
ret, _ = sock.recvfrom()
print((' %08x: ' % addr) + ret.hex())
if ret[0] != 0x80 or len(ret[1:]) != _len:
print('read flash error')
exit(-1)
return ret[1:]

def _write_flash(addr, dat):
print((' %08x: ' % addr) + dat.hex())
sock.sendto(b'\x20' + struct.pack("<I", addr) + dat, (target_addr, 8))
ret, _ = sock.recvfrom()
print(' write ret: ' + ret.hex())
if ret != b'\x80':
print('write flash error')
exit(-1)

def _erase_flash(addr, _len):
sock.sendto(b'\x2f' + struct.pack("<II", addr, _len), (target_addr, 8))
ret, _ = sock.recvfrom()
print(' erase ret: ' + ret.hex())
if ret != b'\x80':
print('erase flash error')
exit(-1)


def read_flash(addr, _len):
cur = addr
ret = b''
while True:
size = min(sub_size, _len-(cur-addr))
if size == 0:
break
ret += _read_flash(cur, size)
cur += size
return ret

def write_flash(addr, dat):
cur = addr
ret = b''
_erase_flash(addr, len(dat))
while True:
size = min(sub_size, len(dat)-(cur-addr))
if size == 0:
break
wdat = dat[cur-addr:cur-addr+size]
_write_flash(cur, wdat)
rdat = _read_flash(cur, len(wdat))
if rdat != wdat:
print(f'rdat != wdat, @{cur:08x}')
exit(-1)
cur += size


if csa_read(R_state, 1)[1] != 0:
print('disable motor first...')
csa_write(R_state, b'\x00')
sleep(1)

print('start motor in position mode ...')
csa_write(R_state, b'\x05')
print('disable anticogging_en first ...')
csa_write(R_anticogging_en, b'\x00')
sleep(1)

print('goto 0 pos...')
csa_write(R_tc_pos, struct.pack("<i", 0))
while True:
sleep(0.5)
if csa_read(R_tc_state, 1)[1] == 0:
print('goto 0 pos ready.')
sleep(2)
break


origin_val = []
for i in range(4096):
pos = i << 4
print(f'i: {i}, pos: {pos}')
csa_write(R_tc_pos, struct.pack("<i", pos))
while True:
sleep(0.5) # 0.2
d = struct.unpack("<ff", csa_read(R_sen_i_sq_avg, 8)[1:])
print(f'd: {d}')
origin_val.append(d)
break # TODO: read the value twice and compare them


print('disable motor ...')
csa_write(R_state, b'\x00')

max_val = [0, 0]
for i in range(4096):
max_val[0] = max(origin_val[i][0], max_val[0])
max_val[1] = max(origin_val[i][1], max_val[1])
print('max_val:', max_val)

flash_val = b''
for i in range(4096):
v0 = round(origin_val[i][0] * 100 / max_val[0])
v1 = round(origin_val[i][1] * 100 / max_val[1])
flash_val += struct.pack("<bb", v0, v1)

print(f'write anticogging data to file: anticogging_data.bin, data len: {len(flash_val)} ...')
with open('anticogging_data.bin', 'wb') as f:
f.write(flash_val)

print(f'write anticogging data to file: anticogging_data.txt')
with open('anticogging_data.txt', 'w') as f:
f.write(json.dumps(origin_val))


print(f'write anticogging data to flash ...')
write_flash(ANTICOGGING_TBL, flash_val)

print('write anticogging_max_val')
csa_write(R_anticogging_max_val, struct.pack("<ff", max_val[0], max_val[1]))

print('enable anticogging_en ...')
csa_write(R_anticogging_en, b'\x01')

print('done, please save to flash by yourself.')

Loading

0 comments on commit 98079b7

Please sign in to comment.