Throttle Speed Matching vesc 6 LISP

Anyone have experience trying to throttle speed match on VESC? Be able to maintain a speed going up or down hill, similar to cruise control but not quite. Been building off a Lisp code I found and wasn’t quite sure how to make or approach throttle speed matching.

any help is much appreciated!

can’t upload the file but will copy paste the code!

; VESC Motor Application 0.0.2

; *************************************************
; Parameters & Definitions
; *************************************************

; ON/OFF Status for Motor Lock
(define ON 1)
(define OFF 0)

; Loop frequency in Hz adjust for Motor Lock responsiveness
(define hz 1000)

; Determines if Motor Locks on bootup
(define isBraking 1)

; Minimum RPM that the motor must be at to initiate Motor Lock
(define minRPM 200)

; RPM that is too high for Motor Lock to engage
(define RPM 300)

; Current RPM
(define curRPM (abs(get-rpm)))

; Motor Lock Current in (A)
(define brakeVal 20)

; Displays PPM variable in Terminal
(define PPM(get-PPM))

; Input Range For Handbrake to engage
; inputTop is the top of the range, inputButtom is the bottom of the range

; Input Value Which AT/BELOW To Engage Handbrake (CHANGE)
; Negative Value Means Handbrake Will NEVER Engage
(define inputTop 0.1)

; Input Value Which AT/ABOVE To Engage Handbrake (CHANGE)
; Negative Value Means Handbrake Will Engage At Any Value Less Than inputTop
(define inputBottom -0.1)

;---------------------------------------------------
; Motor LOCK Function
;---------------------------------------------------

(defun motor_lock()
(progn
; Function for if Motor is UNLOCKED
(if (eq isBraking OFF)
(progn
(app-disable-output -1)
(define isBraking ON)
)
)

; Function for if Motor is LOCKED
(if (> curRPM minRPM)
    (set-handbrake brakeVal)
)

)
)

;---------------------------------------------------
; Motor UNLOCK Function
;---------------------------------------------------

(defun motor_unlock()
(progn

    (if (eq isBraking ON)
        (progn
            (set-handbrake 0)
            (app-disable-output 0)
            (define isBraking OFF)
        )
    )
)

)

; *************************************************
; Main Function
; *************************************************

(defun main()

(progn
    
    ; Definitions that need to be active within loop
    (define PPM (get-ppm))
    (define RPM (get-rpm))
    (define Duty_Cycle (get-duty))
    (define Velocity (get-speed))

    ; Function for determining when to LOCK/UNLOCK motor
    (if (and (< PPM inputTop) (> PPM inputBottom))
    
     (if (or (eq isBraking 1) (< (abs(get-rpm)) RPM)) 
      (motor_lock)
     )
     
     (if (eq isBraking 1)
      (motor_unlock)
     )
     
    )
    
    ; Loop/Loop Rate
    (yield (/ 1000000 hz))
    (main)
)

)

(motor_unlock)
(main)

way i do it, is with my thumb

constantly moving the throttle anyways, so there’s almost no reason to have a constant speed when transitioning attitudes

2 Likes

What is different from what you want and cruise control? because to me it sounds like you just explained how cruise control should work so I am not sure why you need to change the default version.

Also as a tip: you can use code format on here. It is the preformatted text option, or just put ``` before and after the code lines.

Personally I would only worry about keeping a set speed via accelerating or stopping acceleration only. It would make it less accurate for going down hill but you wouldn’t need to worry about your board starting to break without being prepared for it. The last thing I’d want to happen is to fall on my ass in the middle of a hill because it put the breaks on when I didn’t expect it would :scream:

3 Likes

To paste code, put triple backticks before and after the block of code.

You can also research “markdown formatting” on the interwebs.

3 Likes

Do you mean you still want throttle control, but to have hill gradient compensation? You’ll need IMU data for that.

2 Likes

I think he wants duty cycle mode with coast. Basically 50% throttle = 50% of top speed, no matter the load.

3 Likes

Hey thanks for the heads up and tips!

The best way to explain the difference is: Cruise control being you get to the desired speed, and you lock it in, and remove input from the throttle/accelerator, whereas what I’m trying to do is you keep input on throttle and it maintains that specific speed that would be associated at the throttle input range.

say a PPM value of .25 +/- .5 deviation gets you to around 1km/h on flat ground, then you approach a hill and you want to maintain 1km/h up the hill and then later the same speed down the hill. You still have control of the input/stick.

1 Like

This is exactly it!

2 Likes

Yes! However I think it may be possible using the values I’m retrieving: get-PPM, get-duty, get-rpm.

The documentation around Lisp for VESC is pretty detailed

Overview of VESC commands
Language Reference
Lisp - Introduction
Lisp - List Processing
Lisp - Concurrency

A few things to consider when writing the code -

  • Will the regen use regular current control, while the drive will reference duty cycle?
  • If you are coasting downhill and overshoot the duty cycle set by the remote, do you want it to coast and wait or brake to get back on track?
  • You’ll have to do some sort of ramp down when going from say 75% to 25% so it doesn’t brake with all the braking current available.
5 Likes

Here’s the code I have so far, not quite there but wanted to update the status to those who were interested

;           VESC Motor Application 0.0.2

; *************************************************
;               Parameters & Definitions
; *************************************************

; ON/OFF Status for Motor Lock
(define ON 1)
(define OFF 0)

; Loop frequency in Hz adjust for Motor Lock responsiveness
(define hz 500)

; Determines if Motor Locks on bootup 
(define isBraking 1)

; Minimum RPM that the motor must be at to initiate Motor Lock
(define minRPM 200)

; RPM that is too high for Motor Lock to engage
(define RPM 300)

; Current RPM
(define curRPM (abs(get-rpm)))

; Motor Lock Current in (A)
(define brakeVal 20)

; Displays PPM variable in Terminal 
(define PPM(get-PPM))

; Input Range For Handbrake to engage
; inputTop is the top of the range, inputButtom is the bottom of the range

; Input Value Which AT/BELOW To Engage Handbrake (CHANGE)
; Negative Value Means Handbrake Will NEVER Engage
(define inputTop 0.2)

; Input Value Which AT/ABOVE To Engage Handbrake (CHANGE)
; Negative Value Means Handbrake Will Engage At Any Value Less Than inputTop
(define inputBottom -0.2)

; PWM Tolerance
(define PWMtol 0.1)

; RPM Tolerance
(define RPMtol 30)

; Initialization of PWM values to start (for Throttle speed matching)
(define previous_statePWM 0)

; Initialization of RPM values to start (for Throttle speed matching)
(define previous_stateRPM 0)

; Time
(define ticks 0)



;---------------------------------------------------
;               Motor LOCK Function
;---------------------------------------------------

(defun motor_lock()
   (progn
   ; Function for if Motor is UNLOCKED
    (if (eq isBraking OFF)
        (progn
            (app-disable-output -1)
            (define isBraking ON)
        )
    )

    ; Function for if Motor is LOCKED
    (if (> curRPM minRPM)
        (set-handbrake brakeVal)
    )
   )
)

;---------------------------------------------------
;           Motor UNLOCK Function
;---------------------------------------------------

(defun motor_unlock()
    (progn
        (if (eq isBraking ON)
            (progn
                (set-handbrake 0)
                (app-disable-output 0)
                (define isBraking OFF)
            )
        )
    )
)

; *************************************************
;               Main Function
; *************************************************

(defun main()

    (progn
        
        ; Definitions that need to be active within loop
        (define PPM (get-ppm))
        (define RPM (get-rpm))
        (define Duty_Cycle (get-duty))
        (define Velocity (get-speed))
        (define currentstatePWM (get-ppm))
        (define currentstateRPM(get-rpm))

        ; If within bounds        
        (if (and

                ; If PWM is within upper and lower bounds 
                (< PPM inputTop) 
                (> PPM inputBottom)
                (define ticks (+ ticks 0.1))
            )

        ;---------------------------------------------------
        ; Function for determining when to LOCK/UNLOCK motor
        ;---------------------------------------------------
            ; Then do the following:

            ; If motor is locked and the RPM is less than current RPM
            ; Stay locked
            (if (or 
                    (eq isBraking 1) 
                    (< (abs(get-rpm)) RPM)
                )

                ; Then lock motor
                (motor_lock)
            )


            ; If motor is locked and throttle is active
            (if (eq isBraking 1)
                
                ; Then unlock motor
                (motor_unlock)
            )

        ;---------------------------------------------------
        ; Function for throttle speed matching
        ;---------------------------------------------------

        ; If PWM input is relatively constant with regards to tolerance
        ; but RPM is changing
        (if (and 
        
                ; Evaluates currentstatePWM is relatively equal to previous_statePWM
                (if (or

                        (> ticks 3)
                        (eq currentstatePWM previous_statePWM)
                        (<= (abs(- previous_statePWM currentstatePWM)) PWMtol)
                        
                    )       
                )
                ; Evaluates currentstateRPM has changed from previous_stateRPM
                (if (or 
                        (> ticks 3)
                        (> (abs(- previous_stateRPM currentstateRPM)) RPMtol)
                        (< (abs(- previous_stateRPM currentstateRPM)) RPMtol)
                    )        
                )

                (if (eq isBraking 0)) 
                
                    
            )
            
            ; Then do the following :
            ; RPM is set = (previous rpm) + (the loss/gain of current rpm)
            (set-rpm
                (eq
                    (+ previous_stateRPM abs(- previous_stateRPM currentstateRPM))
                
                )
            )

            ; Refresh PWM, RPM and Tick values
            (define currentstatePWM (previous_statePWM))
            (define currentstateRPM (previous_stateRPM))
            (define ticks 0)


        )
        ;---------------------------------------------------
        ; If RPM is relatively constant with regards to tolerance
        ; but PWM is changing
        (if (and 
        
                ; Evaluates currentstateRPM is relatively equal to previous_stateRPM
                (if (or

                        (> ticks 3)
                        (eq currentstateRPM previous_stateRPM)
                        (<= (abs(- previous_stateRPM currentstateRPM)) RPMtol)
                        
                    )       
                )
                ; Evaluates currentstatePWM has changed from previous_statePWM
                (if (or 
                        (> ticks 3)
                        (> (abs(- previous_statePWM currentstatePWM)) PWMtol)
                        (< (abs(- previous_statePWM currentstatePWM)) PWMtol)
                    )        
                )

                (if (eq isBraking 0)) 

            )
            
            ; Then do the following :
            ; RPM is set = (previous rpm) + (the loss/gain of current rpm)
            (set-rpm
                (eq
                    (+ previous_stateRPM abs(- previous_stateRPM currentstateRPM))
                
                )
            )

            ; Refresh PWM and RPM values
            (define currentstatePWM (previous_statePWM))
            (define currentstateRPM (previous_stateRPM))
            (define ticks 0)
        )
         
        )

;---------------------------------------------------                
        ; Loop/Loop Rate
;---------------------------------------------------
        (yield (/ 1000000 hz))
        (main)
        
    )
)

(motor_unlock)
(main)
1 Like

code seems to function more like a set cruise control instead the intended purpose

What is your goal specifically? What do you want it to do?

My number one goal is for the the throttle speed matching that you see on RC cars, you hold a stick input and it holds that same throttle speed despite increasing/decreasing load.

say an input of 1 PPM meant going 8mph on flat ground then it approaches small hill, it maintains that 8mph

Maybe I’m wrong but you want Duty cycle control right?

Controls motor speed based off voltage only. But there’s no freewheel AFAIK.

The PPM remote is set to control duty cycle, I want the LISP code to take the PPM input and adjust the values needed to achieve the expected speed.

example I mentioned earlier:
say an input of 1 PPM meant going 8mph on flat ground then it approaches small hill, it maintains that 8mph

Sounds like you should check out the PID speed control settings.

I feel like once this project is complete most will still prefer current control. That being said, there is work being done here that will help all control modes so I’m happy to see it

3 Likes

the CC on the wand and older NRF based remotes does what you’re asking.
Code is on github

2 Likes