XR-like SURGE Benefits/Discussion/Feature Request

What a neat conversation. I wonder if there are benefits to initiating the boost current based on an additional input. Surge on the XR could be connected to the motor performance so that the motor surges only when you are pushing a certain torque/current threshold. I think this would give you more of a feel for the limits of the motor than the booster as is.

I also wonder if booster can be initiated based on the rate of nose dip instead of just angle. So if you are riding with the motor above the torque threshold, you would only have to dip the nose quick and short to get a bit of boost.

Or perhaps there is a curve for initiation angle compared to torque threshold. At lower torque you require more nose angle to boost. At high torque you can boost with less angle.

This makes me really excited because this is one of the things I love about ATR. It gives me a better sense of the motor torque; how hard the motor is pushing; what roll resistance is my tire is receiving from the terrain.

1 Like

It’s definitely more-so related to the board’s performance / limits than just nose angle like the graph implies. I want to take more time to think about the best way to even try implementing something like this before just tossing in whatever idea first comes to mind, especially with the difficulty of properly testing something like this.

But in general, I’d expect you would want it to kick in specifically when your battery or motor current spikes above a certain threshold relative to their max values, or duty cycle surpasses a certain mark. And at that point basically kick in an extremely aggressive booster (max motor current?) until the nose kicks up closer to setpoint. Hard to say how that kind of approach would work / feel until actually trying it. I’m very comfortable and familiar with FM surge myself, so I look forward to experimenting with it and plan to.

But like Dado said, it’s also important to go into things with a bigger picture mindset, think of how surge benefits us, and think if there’s any potential better way to achieve that result. For this case, maybe surge as-is IS the best tool for the job. I personally can’t think of a better way to handle it currently. But still good to practice approaching things with that mindset nonetheless.

1 Like

Here is a more formalized request. I would test this myself but I am still trying to get qt creator working. I set up using windows though so I will try ubuntu next.

Request: Provide a strong acceleration when pushing the board beyond a certain angle only when the motor is at high torque/current (>50-80%?).

Reason: Currently, there is little feedback when the board is nearing its torque limit without add-ons like a buzzer or metr pro. It is up to the rider to have the right feel for the motor by noticing lack of acceleration. If boost were to only engage when the motor is at high current this would give the rider readily available feedback by quickly dipping the nose to see if it surges. An adjustable torque limit can be used to preserve the boost as it exist now.

Possible Implementation:

		// Current Limiting!
		float current_limit;
		if (d->braking) {
			current_limit = d->mc_current_min * (1 + 0.6 * fabsf(d->torqueresponse_interpolated / 10));
		}
		else {
			current_limit = d->mc_current_max * (1 + 0.6 * fabsf(d->torqueresponse_interpolated / 10));
		}
	if (d->abs_proportional > booster_angle) && (d->atr_filtered_current > (current_limit * 0.7) {	
			if (d->abs_proportional - booster_angle < booster_ramp) {
					booster_current *= SIGN(true_proportional) *
							((d->abs_proportional - booster_angle) / booster_ramp);
				} else {
					booster_current *= SIGN(true_proportional);
				}
			}
			else {
				booster_current = 0;
			}

Yeah the more I think about it the FM surge is most likely duty cycle based. The FM version is most noticeable on uphills and when accelerating hard on flats. It does not seem to be based on dip/pitch decline. Would you agree @NicoAleman ?

I’m also trying to think about this in a way where the goal is not to just replicate what FM did. I spoke with @surfdado on the phone for awhile about this and he mentioned that he thought that if a surge feature were to be implemented, it should not apply to uphill climbing. I think I agree. So first qualifying threshold to enter surge state should be that the nose is below level? Actually maybe 3-5 degrees below level, as you would not want the board to ever surge when you are going fast near level/setpoint?

I originally was thinking this should be triggered by dip/pitch decline rate, as @izzy said, over the last X ms. If the dip rate (decline/time) exceeds a threshold, enter surge state until the dip rate is reversed or at least slowed, or a timeout is exceeded. I don’t think a surge needs to be much more than 1 second? Or maybe just stop evaluating dip rate and surge for the same interval every time? I would think that would be easier.

But yeah the more I think about the FM surge behavior, I would have to guess it is duty cycle based. It can be controllably triggered and tested by accelerating to near nosedive, I think above 5mph or so. It is easier to feel it going up a significant hill. Nosedrags are a great way to feel and test the surge as well :slight_smile: Just based on memory, it definitely feels duty cycle based and not based on dip/pitch change rate.

So please pardon my ignorance with regard to how the firmware and existing ATR features work and are structured. I have yet to dive into the code. In theory a surge could just be triggered by nose down pitch and a duty cycle spike to a predetermined threshold, say 85-90%? I also like the idea of a curve based on duty cycle and pitch. The lower the nose, the lower duty cycle threshold required to trigger the surge/boost. That makes sense to me. If you are nosedragging, you will be in almost constant surge state, which seems to be close to how the FM surge works.

I also don’t know anything about the booster feature. How does that work?

@surfdado also suggested a completely different method of alerting the rider, such as a vibration of the motor, as they are nearing the limits of the board. This is interesting because he said that could be more efficient and essentially current/amp neutral, so you could do this without using and requiring more power. So the rider will feel a vibration instead of an acceleration surge as they approach duty cycle limits. This is interesting and would be cool to test, but I think part of the utility of the surge is also to help the rider rebalance before they get to nosedive conditions. Especially when the nose is way down. I know the FM surge has helped me rebalance when I am too nose heavy and Austen and Neil say that it has saved them countless times. The vibration could be a really nice feature at top speeds when the board is near level and you are approaching duty cycle limits. And the surge would not apply in those conditions.

Best to wait till you can build your own code. Just install a virtual machine and it’ll compile super easily. Your change is flawed for multiple reasons so it really is best if you can do trial and error yourself without having us in the loop…

I have 2 6s LiPo packs coming in today to create a low-voltage testboard for this. Should be testing my surge behavior this weekend… (at 24Volts instead of 60V+ so should be right around 10mph when I hit 90%+)

3 Likes

I’d be happy to jump on a call with you to discuss this - back and forth here will just take way too long…

Yea, I agree. I’d like to just be testing myself. Probably should of just started with VM. Rainy days this weekend so no time like the present.

Thanks for the confirmation that it is not as easy as I thought. Trying to put some variables to the feels. There’s only so many inputs and outputs so I just took a swing. I really appreciate the call offer, but I should probably mess around first. I get the sense I’m not quite on a level to understand all knowledge you have to share so I’ll do some experimentation until I’m ready to ask the right questions. Sounds like you got some experiments of your own brewing so you might have it figured out by the time I catch up.

1 Like

So, who’s down to try it out?
Surge behavior in Float Package - Firmware Customization and Testing - pev.dev

My surge code has been coming along well so I wanted to update ya’ll on what I have been working on. Ashton’s perspective was super helpful in identifying the behavior for me. Until I read this post, I did not realize what I have been missing from the onewheel. Here is how my code works.

Surge, by its nature, is a dynamic state. You will see the surge state itself is quite simple, but because it is so dynamic, the conditions that engage and disengage surge are very important. So what is the surge state? It is the motor being driven to maximum duty using the VESC IF function mc_set_duty(). The effect of this is quite predictable. The nose will go up fast and hard so how do we control this.

First, we set some time limits so we cannot surge uncontrolled. I have set up to surge for 250ms on a 750ms period so there will be a minimum of 500ms between each surge. I believe this period is close to what it feels like when you are inching up a steep hill.

Next, we have to know when to engage surge. We want surge to start at a very high torque (current). This will allow a smooth transition into surge because we are already applying a significant amount of force to the front footpad so it will not nose up too quickly.

Finally, we have to know when to end the surge or else the board will remain out of our control. First, we need to make sure we are still accelerating after the surge so we want the nose to be pitched down a minimum angle. If we are pitched up, surge ends with an abrupt brake, which can make you lose control. Second, the pitch cannot be traveling too fast back to center. This could make us overshoot our minimum angle. Lastly, we want some traction control so we don’t lose control during wheel slip.

I am at the point where the code works and I am massaging the start and stop conditions. There is also a vesc if function mc_set_duty_noramp that I have not tried yet. You are welcome to check out my code Izzygit · GitHub Surge9 branch, but be aware that only the main branch is released. No precompiled package yet. I don’t know how to write UI yet so my UI is kind of hacky. It uses the inputs from turntilt and I changed the AppUI.

Here are some examples. Debug data shows time since last surge, duty before surge, duty at end of surge, reason for surge end. If angle speed>0, that was the fault. If angle speed=0, it was a pitch fault. If pitch fault=100%, it was traction control.

Mid speed surge

Low speed surge

Bonk resulting in traction control fault (100% pitch fault)

1 Like

I’m still workin away at my surge code. I’m very excited to release it but it is still not quite smooth enough transitioning from surge back to PID control in all situations. Particularly at higher speeds, 7000+ erpm, but I think I have a cure for that. I was able to take it for a trail ride last weekend and it performed great in lower speed, high torque situations.

There are now two triggers to surge. The primary trigger is nose angle speed, specifically in the downward direction. Once you hit this threshold the board will surge. This feels very much like the surge from dipping the onewheel nose.

The second trigger is high continuous current. This would be situation where you are going up a very steep hill and the board starts pulsing. This could also engage when the board starts to stall. My question is, probably specifically for @surfdado, how do I identify the maximum continuous current that we should start surging? The data I have gathered shows that the standard hypercore (120A motor/30A battery) setup is giving me anywhere from ~55-65 A of continuous current. So I am thinking I would like to surge if we maintain something like 55A for 500ms as a starting point. Is there anyway to identify this amperage value for different setups via VESC IF? I imagine this value can vary quite a bit from motor to motor. Thanks.

Pretty sure there’s no concept of continuous currents in the VESC code base. But the VESC_IF lets you call something like get_tot_current - but the float package already does that so you already have access to the actual motor current.

I just noticed your post from 10 days ago. As far as I’m concerned surge when at the speed limit is the only situation I’m interested in. How do you plan on making it (a) noticeable and (b) safe?

Also I’m questioning whether the nose angle speed trigger is something we really want - aren’t you simply preventing nosedrags? Don’t we already have other mechanisms to basically disable nosedrags? Like booster and torquetilt?

Not exactly sure how to answer. What I am doing right now is attempting to mimic the onewheel behavior. Whether or not everything about that is desirable or not, I will let the community decide. I have been switching back and forth between my onewheel and VESC and I am quite close to the same feel with some additional improvements. The advantages I see thus far are:
Crisper and higher curb nudges
Stronger reaction to nose diving
Fun feeling for acceleration if you commit your weight to your front foot after initiating surge. Essentially max acceleration.
Forward burnouts like the onewheel (surge forward and deweight while on dirt)
Pulsing while climbing at max torque to prevent nose dive (still working on this)
Surging at speed lets you feel how far from max duty you are by judging the reaction. The reaction feels softer at high duty.

When compared to booster, the surge reaction is stronger because it is the strongest continuous reaction the motor can have. I think for that reason alone it will have value. I think trick riders and dirt riders are going to see the most benefit.

I have not used torquetilt for nose dive prevention. I’m not a big fan of sharp setpoint changes because it makes the board feel a little tight. I will give it a try on my next trail ride. I am dubious about the efficacy because nose dives happen at 100+ deg/s and I don’t know if torquetilt will react fast enough without being too crazy in other situations.

Thanks for your response on the motor current.

Here is some nice data I collected. This is 3 surges in quick succession at relatively low speed. Full time scale is 5 seconds.

1 Like

I guess I’m still confused about the purpose of this. How do you even nosedive with a VESC? What situations lead to a nosedive for you? My XR nosedives all the time on steep trails. My VESC never does, so I’m still confused about the exact situations where this would be of benefit.

Correction: my VESC does actually nosedive in one case: when I hit max duty, but at this point your “surge” would be of no benefit because it merely requests max duty - but we are already at max duty, so nothing happens…

I will explain the best I can. A nose dive is simply your body weight being too far in front of the wheel so that the board cannot react fast enough or it does not have any more power to give you. What you describe is the situation where the board not having any more power to give but that isn’t really the situation that concerns me or other experienced riders I think.

Nose dives can also occur because of sudden change in terrain or objects that rapidly decelerate the board. Naturally you want to move your weight back when this happens to avoid nose dip but when going hard on a trail it’s not unusual to misjudge or not see something. In that case your weight can go too far forward and the nose starts dipping fast. Surge counters this by driving your current and duty to the max continuous in an effort to get your nose up as quickly as the motor is capable of.

Here is an example from my last trail ride. I’m going down a decent slope and I see a rock I want to bonk. It’s maybe 4 inches tall and very rectangular, like no slope to it. I know it’s going to be a rough go but I decide not to slow down and just go for it at 12mph or so. I clear it and get some nice air but it decelerated my board quite a bit. I didn’t counter the deceleration enough with my body position so the wheel is a bit behind me. I land hard and the nose goes straight to the ground. The surge engages and it slides me another 1-2ft, but I’m can’t shift my weight back fast enough to get off the front pad. I run it out pretty easily. Had the surge not engaged, the nose would have planted and I would probably be on the ground so i considered that a minor success.

In short surge is max motor performance when you need it (i.e. nose dives) or ask for it (i.e. curb nudge).

1 Like

Thanks for explaining, I still have a hard time wrapping my head around this though - it sounds like you are attributing the behavior you experienced to “surge” but are you sure this wouldn’t have also happened without it? Have you tried it?

Your use case with the downhill bonk and nosedive landing basically describes a situation where even without surge you should get max amps almost immediately, maybe your surge logic allows max amps to kick in a few milliseconds earlier, but overall the behavior should be very similar.

I started this endeavor by adjusting the booster. I would force the booster to maximum amps until back at the setpoint. I found this did not change the feel of the booster much. I found the same effect from just forcing high amps when a high amp trigger is met. It felt like a dead end. My conclusion was that the booster is in a good place as it is.

So your question is, what makes surge different from booster? You are right that the differential trigger allows for a slightly earlier reaction but while that helps, I don’t think that is the true effect I am feeling.

And this is where I might be talking out of my ass because it gets more technical than my qualifications, but this is the best I can figure. When you use the set duty function instead of the set current function the controller is now using the duty as it’s control value. This allows it to “lead” with higher duty and the amps become a result, instead of leading with high amps and the duty being the result. Duty is related to the apparent voltage received by the motor and seems somewhat restricted by erpm. By leading with higher duty we can deliver both the maximum possible, apparent motor voltage (at the current erpm) and maximum continuous amps immediately.

I am eager to get this code in a releasable state to get other people opinions. Sometimes I worry that I am losing the plot. Having done some many tests and so many surges you start to forget what feels different. But I jump on my onewheel and I do feel like it is so close to being the same.

I went on a 20 mi trail ride this weekend at a park notorious for really choppy trails from all the cows. I learned that my current code was total garbage. Worked on streets but trash on real challenging terrain. But from the ashes I figure a new surge end condition that I was able to get working on my first try that night. It is way smoother and there are significantly less variables. The code is in a good place right now if you want to check it out, branch Surge13. It uses turntilt for the entries and displays those entries on AppUI with appropriate debugs.

It feels like the onewheel actually overreacts more than the current code so that is what I am considering now. I expect at least one more trail ride before release but I am feeling pretty good about it today.

1 Like

Hey Izzy I really like everything you posted and I think you are really understanding why the XR surge is so valuable. It is a repeatable analog power meter you can tap into at any speed under any condition at any time. Want to know how much more power you have on tap while going uphill? Press the nose down hard and feel how hard the board pushes back on your leg, that weight is the precise amount of weight the board will hold on the nose since you know surge is 100% power. So now you can put exactly that much weight on the front (a lil less for safety) and start going up the hill.

Has your code gotten somewhere where others can try it out? I’ve been super busy at the shop and basically forgot about this topic after I didn’t really like the duty cycle implementation cause thats basically just a speed warning and surge is more of a torque warning. Going uphill is actually one of the places I want it most! And someone mentioned FM surge being DC based but that couldn’t be since you can trigger it at 0 mph. My personal thoughts are that its start condition is purely % of max current based and being below setpoint. stop maybe just getting back to setpoint.

Now that I have many miles on my vesc and I have really started to push the limits of its straight line accelerations, Im finding a lack of TQ warning to be unsettling when at the very edge. I have no analog gauge/meter to know what is left on tap when I really hit the gas pedal. I really miss being able to calibrate to the board via the pressure on my front foot during surge.

One question I had was you mentioned you can only have one surge per 500ms, does that mean that you cant “ride the surge” like on the XR? or does your surge, once triggered, still wait for the stop condition.

Thanks!!