Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] AMK Motors (the car will move soon) #137

Draft
wants to merge 36 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ee7b4c9
it does not work :(
ColexDev Sep 19, 2024
0a47414
Messing with motors, it will compile now, just some odd W5500 error?
ColexDev Sep 22, 2024
7e1a7d2
not sure about pgn, but found default msg period in the datasheet
ColexDev Sep 22, 2024
3c32825
Setting up CAN, I think I got the signals figured out in the json?
ColexDev Sep 27, 2024
f031a10
CAN is going well, maybe not :)
ColexDev Sep 27, 2024
8d69ad1
outlined steps for turning on and off motors
ColexDev Oct 11, 2024
fe85dc7
This datasheet sucks
ColexDev Oct 12, 2024
0c92262
Either our CAN setup is not good for these motors, or I am dumb
ColexDev Oct 12, 2024
130723a
we love state machines
ColexDev Oct 13, 2024
aa8fb80
too easy
ColexDev Oct 13, 2024
8c37d04
deinit state machine basics are setup
ColexDev Oct 14, 2024
114d546
Trying to figure out more about these motors
ColexDev Oct 14, 2024
7b33e27
Added logic in switch statements. Also we need to move to torque cont…
ColexDev Oct 19, 2024
4c416f0
Starting to add messages from my notes into the can config
ColexDev Oct 26, 2024
8cfcb8c
Added all free signals to the config, need to change the init and dei…
ColexDev Oct 28, 2024
06097c0
Just thinking about how to implement the actual torque stuff and turn…
ColexDev Oct 28, 2024
d92e969
hoping to get state machine stuff finished soon so I can move into mo…
ColexDev Oct 29, 2024
a61d8f4
State machines are sort of done
ColexDev Oct 30, 2024
cf63093
Starting to get data into struct, I should have it nicer but I think …
ColexDev Oct 30, 2024
7dc3c04
Just some notes and small changes, still figuring some stuff out
ColexDev Oct 30, 2024
76748c7
formatting fix plus got rid of state that was unncessary
ColexDev Oct 30, 2024
7679500
Finally got AMK building in, calling stuff in car.c now. Not sure if …
ColexDev Nov 1, 2024
099e108
Oops, forgot to commit cmakelists
ColexDev Nov 1, 2024
9275557
I still have no idea what to do with these torque limits, maybe what …
ColexDev Nov 1, 2024
7e581a4
pushing correct scaling, they can deal with it on TV and Dash, unless…
ColexDev Nov 3, 2024
08896c3
Starting error stuff
ColexDev Nov 4, 2024
c09aaf2
Modified pinouts for Main MCU 25
ColexDev Nov 4, 2024
6143182
Mix of removing UART and some testing stuff
ColexDev Nov 15, 2024
c264034
not too much rn
ColexDev Nov 17, 2024
dea5733
Some additions based on the meeting we had with UIUC
ColexDev Nov 17, 2024
7dbb3a2
Adding error handling stuff, no idea if its gonna work. Just like eve…
ColexDev Nov 17, 2024
b82f602
Motors are in the car struct
ColexDev Nov 17, 2024
3a8ad12
Don't even know why that was there
ColexDev Nov 17, 2024
6b379f7
Some review stuff
ColexDev Nov 21, 2024
c41eb3a
trying to do can2 but cannable isn't working?
ColexDev Dec 6, 2024
b29289a
Why isn't this working??
ColexDev Dec 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions common/amk/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
set(TARGET_NAME amk)
add_library(${TARGET_NAME})

# Find all .c sources in project
#file(GLOB_RECURSE glob_sources "*.c")
target_sources(${TARGET_NAME} PRIVATE "amk.c")

# Find directories for '#include'
# For libraries, these directories are all referenced to the top level firmware directory, CMAKE_SOURCE_DIR
target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_SOURCE_DIR})

target_link_libraries(${TARGET_NAME} "QUEUE;common_defs;PHAL_F407")

244 changes: 244 additions & 0 deletions common/amk/amk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
#include "amk.h"
#include "source/main_module/can/can_parse.h"


/* NOTE:
* I need change all of this to be a massive state machine in one function
* like car.c. It will have states such as init which will turn motors on,
* and a state to turn motors off and a state to actually run stuff.
* The massive state machine will run periodically (not sure how often yet,
* has to be < 50ms so that the control word can be send often)
*/

/* NOTE:
* Step 1 is turning on LV
* Step 3 happens when HV is turned on and precharging starts
* I can check when this is done with precharge complete and then move
* onto other steps
* MAYBE we can check when AMK_bSystemReady is on and display a message
* on LCD so they know when to turn on the HV to start the precharging.
* Not sure if I need that
*/

static amk_motor_t motor = {0};

static AMK_Control_t control = {0};
static AMK_Status_t status = {0};

static void turnMotorsOn();
static void motorsRunning();
static void turnMotorsOff();

/* NOTE: As of now this is just setting everything to 0, but it may make sense
* to have it in case something changes down the line while I learn more, so
* this may end up being deleted if everything just inits to 0 */

/* FIXME: Move control word and status words into motor struct */

void motorInit(amk_motor_t* motor)
{
*motor = (amk_motor_t){
/* States */
.states.stage = MOTOR_STAGE_INIT,
.states.init_state = MOTOR_INIT_POWER_ON,
/* FIXME: FILL IN ONCE I MAKE ENUMS */
.states.deinit_state = 0,
.states.running_state = 0,

/* Values */
.values.target_velocity = DEFAULT_TARGET_VELOCITY,
.values.torque_limit_positive = DEFAULT_POSITIVE_TORQUE_LIMIT,
.values.torque_limit_negative = DEFAULT_NEGATIVE_TORQUE_LIMIT
};
}

void motorPeriodic()
{
switch(motor.states.stage) {
case MOTOR_STAGE_INIT:
turnMotorsOn();
break;
case MOTOR_STAGE_RUNNING:
motorsRunning();
break;
case MOTOR_STAGE_DEINIT:
turnMotorsOff();
break;
}
}

static void motorsRunning()
{
/* Set setpoint settings (AMK_TargetVelocity, AMK_TorqueLimitNegativ, AMK_TorqueLimitPositiv) */
SEND_AMK_SETPOINTS_1(control.bits,
1,
1,
1);
}

static void turnMotorOn(amk_motor_t* motor)
{
/*
* Motor Datasheet:
* https://www.amk-motion.com/amk-dokucd/dokucd/en/content/resources/pdf-dateien/pdk_205481_kw26-s5-fse-4q_en_.pdf
*
* Section 9.4 goes over turning the motors on and off
*
* Steps with the "r" suffix are requirement steps, the requirement needs to
* be met before moving onto the next step.
*/

switch (motor->states.init_state) {
case MOTOR_INIT_POWER_ON:
/* 1. Turn on 24V DC to inverters */
/* 1r. Check AMK_bSystemReady = 1*/

/* if AMK_bSystemReady = 1 */
motor->states.init_state++;

break;
case MOTOR_INIT_PRECHARGE:
/* 2. Charge DC caps; QUE should be set (is this just DcOn?) */
/* This step happens when HV turns on. I can check the precharge
* complete GPIO pin to see when this is finished. When finished
* I move onto the next state. */

/* if precharge complete pin is high */
motor->states.init_state++;

break;
case MOTOR_INIT_DC_ON:
/* 3. Set AMK_bDcOn = 1 */
control.fields.AMK_bDcOn = true;
SEND_AMK_SETPOINTS_1(control.bits,
motor->values.target_velocity,
motor->values.torque_limit_positive,
motor->values.torque_limit_negative);
motor->states.init_state++;
break;
case MOTOR_INIT_DC_ON_CHECK:
/* 3r. AMK_bDcOn is mirrored in AMK_Status, so should be on there */
status.bits = can_data.AMK_Actual_Values_1.AMK_Status;

/* When will AMK_bQuitDcOn go on? Does it take some time after
* DcOn is set?? */
/* 3r. (QUE & AMK_bDcOn) -> Check AMK_bQuitDcOn = 1 */
/* Does where do I check QUE??? */

motor->states.init_state++;
break;
case MOTOR_INIT_TORQUE_INIT:
/* 4. Set AMK_TorqueLimitNegativ = 0 and AMK_TorqueLimitPositiv = 0 */
motor->values.torque_limit_positive = 0;
motor->values.torque_limit_negative = 0;

SEND_AMK_SETPOINTS_1(control.bits,
motor->values.target_velocity,
motor->values.torque_limit_positive,
motor->values.torque_limit_negative);

motor->states.init_state++;
break;
case MOTOR_INIT_ENABLE:
/* 7. Set AMK_bEnable = 1 */
control.fields.AMK_bEnable = true;
SEND_AMK_SETPOINTS_1(control.bits,
motor->values.target_velocity,
motor->values.torque_limit_positive,
motor->values.torque_limit_negative);

motor->states.init_state++;
break;
case MOTOR_INIT_INVERTER_ON:
/* 8 Set AMK_bInverterOn = 1 */
control.fields.AMK_bInverterOn = true;
SEND_AMK_SETPOINTS_1(control.bits,
motor->values.target_velocity,
motor->values.torque_limit_positive,
motor->values.torque_limit_negative);

motor->states.init_state++;
break;
case MOTOR_INIT_INVERTER_ON_CHECK:
/* 8r. AMK_bInverterOn is mirrored in AMK_Status, so should be on there */

/* Same with AMK_bQuitDcOn, do we need seperate states for these quits?? */
/* 9. Check AMK_bQuitInverterOn = 1 */

/* This should be the last init state, so now we move onto the stage for
* running the motors */

motor->states.stage++;
break;
}
}

static void turnMotorOff(amk_motor_t* motor)
{
/*
* Motor Datasheet:
* https://www.amk-motion.com/amk-dokucd/dokucd/en/content/resources/pdf-dateien/pdk_205481_kw26-s5-fse-4q_en_.pdf
*
* Section 9.4 goes over turning the motors on and off
*
* Steps with the "r" suffix are requirement steps, the requirement needs to
* be met before moving onto the next step.
*/

switch(motor->states.deinit_state) {
case MOTOR_DEINIT_SETPOINTS_DEINIT:
/* 1. Set setpoint settings to 0 (AMK_TargetVelocity, AMK_TorqueLimitNegativ, AMK_TorqueLimitPositiv) */
motor->values.torque_limit_positive = 0;
motor->values.torque_limit_negative = 0;

SEND_AMK_SETPOINTS_1(control.bits,
motor->values.target_velocity,
motor->values.torque_limit_positive,
motor->values.torque_limit_negative);
motor->states.deinit_state++;
break;

case MOTOR_DEINIT_INVERTER_OFF:
/* 2. Set AMK_bInverterOn = 0 */
control.fields.AMK_bInverterOn = true;

SEND_AMK_SETPOINTS_1(control.bits,
motor->values.target_velocity,
motor->values.torque_limit_positive,
motor->values.torque_limit_negative);

motor->states.init_state++;
break;
case MOTOR_DEINIT_INVERTER_OFF_CHECK:
/* 2r. AMK_bInverterOn is mirrored in AMK_Status, so should be on there */
motor->states.init_state++;
break;
case MOTOR_DEINIT_DISABLE:
/* 3. Set AMK_bEnable = 0 */
motor->states.init_state++;
break;
case MOTOR_DEINIT_QUIT_INVERTER_CHECK:
/* 4. Check AMK_bQuitInverterOn = 0 */
motor->states.init_state++;
break;
case MOTOR_DEINIT_DC_OFF:
/* 5. Set AMK_bDcOn = 0 */
motor->states.init_state++;
break;
case MOTOR_DEINIT_DC_OFF_CHECK:
/* 5r. AMK_bDcOn is mirrored in AMK_Status, so should be on there */
/* 5r. Check AMK_bQuitDcOn = 0 */
motor->states.init_state++;
break;
case MOTOR_DEINIT_PRECHARGE:
/* 6. Discharge DC caps; QUE should be reset (is this just DcOn?) */

/* If discharged, move on */
motor->states.init_state++;
break;
case MOTOR_DEINIT_POWER_OFF:
/* 7. Turn off 24v DC to inverters */
motor->states.init_state++;
break;
}
}
102 changes: 102 additions & 0 deletions common/amk/amk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
* @file amk.h
* @author Cole Roberts (rober638@purdue.edu)
* @brief Vroom
* @version 0.1
* @date 2024-10-11
*
* @copyright Copyright (c) 2024
*
*/
#ifndef _AMK_H_
#define _AMK_H_

#include <stdbool.h>
#include <stdint.h>

typedef struct {
uint8_t stage;
uint8_t running_state;
uint8_t init_state;
uint8_t deinit_state;
} amk_motor_states_t;

typedef struct {
uint16_t target_velocity;
uint16_t torque_limit_positive;
uint16_t torque_limit_negative;
} amk_motor_values_t;

typedef struct {
amk_motor_states_t states;
amk_motor_values_t values;
} amk_motor_t;

typedef enum {
MOTOR_INIT_POWER_ON,
MOTOR_INIT_PRECHARGE,
MOTOR_INIT_DC_ON,
MOTOR_INIT_DC_ON_CHECK,
MOTOR_INIT_TORQUE_INIT,
MOTOR_INIT_ENABLE,
MOTOR_INIT_INVERTER_ON,
MOTOR_INIT_INVERTER_ON_CHECK,
} amk_motor_init_state_t;

typedef enum {
MOTOR_DEINIT_SETPOINTS_DEINIT,
MOTOR_DEINIT_INVERTER_OFF,
MOTOR_DEINIT_INVERTER_OFF_CHECK,
MOTOR_DEINIT_DISABLE,
MOTOR_DEINIT_QUIT_INVERTER_CHECK,
MOTOR_DEINIT_DC_OFF,
MOTOR_DEINIT_DC_OFF_CHECK,
MOTOR_DEINIT_PRECHARGE,
MOTOR_DEINIT_POWER_OFF,
} amk_motor_deinit_state_t;

typedef enum {
MOTOR_STAGE_INIT,
MOTOR_STAGE_RUNNING,
MOTOR_STAGE_DEINIT
} amk_motor_stage_t;

/* Inverter -> CAN */
/* In AMK_Actual_Values_1 */
typedef union
{
struct {
uint16_t AMK_bReserve : 8;
uint16_t AMK_bSystemReady : 1;
uint16_t AMK_bError : 1;
uint16_t AMK_bWarn : 1;
uint16_t AMK_bQuitDcOn : 1;
uint16_t AMK_bDcOn : 1; /* Same as QUE ?? */
uint16_t AMK_bQuitInverterOn : 1;
uint16_t AMK_bInverterOn : 1;
uint16_t AMK_bDerating : 1;
} fields;
uint16_t bits;
} AMK_Status_t;

/* CAN -> Inverter */
/* In AMK_Setpoints */
/* THIS NEEDS TO BE SENT EVERY 50ms */
typedef union
{
struct {
uint16_t AMK_bReserve1 : 8;
uint16_t AMK_bInverterOn : 1;
uint16_t AMK_bDcOn : 1;
uint16_t AMK_bEnable : 1;
uint16_t AMK_bErrorReset : 1;
uint16_t AMK_bReserve2 : 1;
} fields;
uint16_t bits;
} AMK_Control_t;

#define DEFAULT_TARGET_VELOCITY 0
#define DEFAULT_POSITIVE_TORQUE_LIMIT 0
#define DEFAULT_NEGATIVE_TORQUE_LIMIT 0

#endif /* _AMK_H_ */
Loading