image_pdfimage_print

Design Validation of Custom Electronic Throttle Body

In this article I explain how system modeling was used to validate some of the design decisions of an electronic throttle body (ETC). I go over the context and motive behind designing an ETC. Then the physical design of the ETC is briefly covered.

Context

Before focusing solely on the EV side of my Formula Student Team I wanted to develop one last component specific to IC vehicles. When I assembled my first Formula Student car (circa 2017), I realised one of the most unreliable components was the throttle actuation. Frequently, this actuation mechanism is badly designed leading to, in most cases, to a throttle body closing slower than optimal. The unreliability usually arises from badly chosen springs as well as friction along the throttle cable. The solution that has been devised eliminates these sources of unreliability entirely and is identical to throttles used in all new production vehicles, albeit with different requirements.

Many FS teams have already implemented Electronic Throttle Control (ETC) on their cars but practically all of them use an off the shelf solution, frequently the Bosch ETC. System Complexity & stringent competition rules are the main challenges FS teams face to developing their own ETC. In this project, I attempt to mitigate these two problems by using simulation to verify my design, which also serves as documentation for the competition’s Tech inspection.

Personally, I believed designing an ETC at this moment in time would be a very good opportunity to gain an understanding of Matlab’s Multiphysics environment (Simscape) as I hope to use it frequently in the EV development (more on that later), and there is no better way to learn something than to apply it to a real life situation.

Requirements

  • The ETC must be able to use the existing mounting strategy
  • The ETC will use the same diameter (∅32mm)
  • The ETC must carry a Throttle Position Sensor (TPS) that has 2 outputs with independent power supplies
  • The weight of the ETC must be under 350g (previous TB: 200g+ cable & Housing:150g)
  • Lag from 0% to 100% Throttle must be less than (<)400ms

Design

Exploded View of ETC

The ETC is based on a barrel-type throttle body. Barrel throttle bodies offer an unrestricted pathway, and therefore, the best flow characteristics at wide open throttle (WOT) as compared to a butterfly valve. They are also easily actuated compared to slide throttles that require translation motion compared to just rotational motion. Barrel throttle bodies are not common in OEMs due to their increased cost. To build a barrel throttle body in large numbers you would need a minimum of 3 casted components, which is 3 times more than a traditional butterfly throttle body.

Manufacturing wise the most complex component will be the throttle barrel as it will require machining on a lathe and then on a mill, even then it is not extremely intricate. Whilst the throttle housing may look complex having access to a 5-axis mill reduces the setup stages down to 2. The machining jig used to make the previous cable based throttle body may be used as the mounting holes remain the same.

Igus flange bearings offer very predictable operation and require no maintenance, as well as low weight and low cost. Iglidur J flavour is chosen as it offers reduced wear and low coefficients of friction compared to other polymers.

The Variohm XPD sensor has two Hall analog outputs with their own power supply wiring. This meets the Formula Student rules.

The Gear Side Cover is a 3d printed component in ABS that creates an enclosure around the gearing as well as containing the rotational end stops for the throttle.

The Re-385 is an inexpensive DC brushed motor that meets the set requirements. More on this in the appendix.

The gearing has been chosen given the tight spatial constraints, for an overall gear reduction of 8. This ratio is verified by the simulation below. More details on the durability of these can be found in the appendix.

The Spring choice was carefully chosen and validated using the simulation. It allows for high preload even with a small spring constant, a feature common in springs with a large number of turns.

Animation of the Throttle Internals

Simulation

Motor analysis

The RE-385 specs are summarised below:

Motor SpecsRE-385
Nominal Voltage 12V
No-Load Current0.18A
No-Load Speed11646rpm
Stall Torque 50.4mNm
Stall Current5.55A
Motor Specs

With this data I was able to plot the motor characteristic curves on Matlab. This graph is used to identify the performance of the motor at the chosen operating points. It helps us to determine if the motor will be running too stressed (failing prematurely) or if it is overpowered for the application. The motor friction can also be identified by extrapolating the Current-Torque line until it crosses the 0A line, this value is important when choosing the spring preload.

RE-385 Characteristic Curves

Simscape Model

In order to ensure the motor selection and gear reduction was appropriate I built a Simscape model to simulate the end product. Simscape is a multi-physics library inside Simulink where I can model electrical and mechanical systems combined.

Brushed dc motor position control is not very well documented and practically no creations exist so the model built is quite novel in this enviroment. Simscape is mostly used with the more modern brushless motors and all documentation for dc motors use speed based control.

Electronic half of Simulink Model

Implementing position control is not complicated as the only big difference with a speed control model is that the feedback loop contains the angle rather than the angular velocity. The PID block has been setup as time-discrete instead of time-continuous in order to make it realistic. It has also been setup to saturate the signal between -5 & +5 volts in order to prevent discontinuities in the model.

The motor is driven through an H-bridge block that is controlled by a PWM signal. Additionally the reverse functionality of the h-bridge is triggered when the signal on the REV terminal exceeds +2.5 volts. The motor is run in reverse when the output of the PID block is negative.

The DC motor model in Simscape allows the user to use different parameter sets to model the motor not just the traditional motor constants. A user can model the motor just by knowing the stall torque, No-load Speed and No-load current, this makes the block very accessible and easy to setup. It also leads to a model that is fairly complex but not robust, this is why a current limiter is placed before the DC motor, preventing it from exceeding its stall current.

Mechanical half of Simulink Model

This model is a systematic version of what has been modelled on cad. It includes most of the constant losses and the parasitic losses, it should allow a good representation of how the throttle will function in real life.

Motor Friction is included and its value was identified from the motor characteristics plot. Both gearbox blocks represent the meshing of gears, their ratios are 40/14 and 14/5, both have been given a conservative efficiency of 90% of the torque input. The friction due to the bearings is also included and has been calculated using the friction coefficient provided by Igus (0.19) X the weight of the barrel + 80T gear.

The Clock Spring is modelled with its decided pre-load and supplier provided spring rate. The Rotational Hard Stop prevent the Throttle from rotating below the 0% and 100% set angles. The Clock Spring, Igus Bearing Friction and Rotational Hard Stop are all parallel as they act on the same shaft.

The Hall Sensor allows us to retrieve the throttle angle.

This model also allows us to confirm that the pre-load torque of the motor is sufficient to restore the throttle to 0% in the case of loss of power. Under 500ms (as defined by T11.8.12 of 2022 FS rule book).

Complete Simscape model

Results

I first simulated the the operation at 100% throttle:

Simulated Throttle Response for a 0->100% step input @1sec

100% throttle corresponds to 90deg of displacement or WOT. The operation at this position will represent the largest continuous current and therefore largest continuous motor stress. Current spikes during acceleration to 90deg are realistic as the PID attempts to accelerate & decelerate the system as fast as possible. The stability of the PID can be seen as the current flattens out. We can see how the preload works as the Spring Torque does not begin at 0 but at 72mNm.

We can identify another discrepancy in the Simscape motor model by comparing the resultant motor current and motor torque to the values on the motor characteristics plot. We see that the simulated current is around 240mA lower on the characteristic plot.

Regardless, we can identify from the resultant torque on the characteristic plot that this operating point is valid as it sits inside the line.

Simulated Throttle Response for a 0->10% step input @1sec

A 10% Throttle opening or 9deg is also simulated to verify the operation at a value close to throttle idle. Given that there is no idle screw on the throttle, the motor will be in charge of keeping it open during idling. This operating point is where the throttle will be at most of the time and therefore necessary to be analysed.

The PID controller is also proven to be stable at this point as the current flattens. Likewise we once again see the discrepancy between the characteristic plot and the results in the motor current.

As expected the motor torque is within the achievable values.

In order to meet one of my requirements I had to make sure that the throttle responded fast enough to throttle input.

Focused Throttle Response for 0->100% Step input


The response of the 0º to 90º throttle opening is plotted and we see that the throttle is extremely fast. Even with the manually tuned PID constants the throttle is able to achieve a 2% settling time of 56.7ms.

Conclusion

Plotting the Characteristic Curves with the motor operating points gives us a good image of the motor reliability and efficiency.

RE-385 Motor Characteristic Curves with operating points

The motor current at 100% throttle is ~28% of the stall current, this is lower than the 40% max recommended by motor manufacturers in order to prevent noticeable pre-mature failure. At its most prevalent operating point (10% opening) the motor current is only 21% of the stall current further more promoting reduced wear.

Whilst thermal effects are not considered in the simulation, plotting the above graph allows us to see that at these operating points the motors are unlikely to experience overheating given the low motor stress. Furthermore, the housing is bolted to an aluminium surface.

Seeing that the operating points sit between the max power and max efficiency points allowing us to confirm that the motor choice is indeed appropriate and not overkill. Using a smaller motor for the same system would lead to a big decrease in power, delivering a slower response and a larger motor stress.

Ideally current consumption at the idle point would be extremely close to the no-load current, however, this is dependent mainly on the spring chosen and springs available that fit to the spatial and operational requirements are limited.

Overall it can be confirmed that the choice of motor and gearing is appropriate for this application given the requirements. The small settling time is very small and will strongly depend on the PID controller implemented in the ECU, therefore it is likely to increase in reality.

Comparing to the most common ETC solution for FS teams. The developed throttle is 60% lighter than the Bosch 32mm ETC (277g vs 900g). The throttle response is 78% faster (56.7ms vs 265ms)

The size of the Custom throttle is much smaller, this is due to the Bosch ETC using standardised components from its whole line up.

Next stages for this throttle are to receive approval for manufacture by the appropriate sub-team leaders. Once assembled the throttle will be tested to compare with the simulated results.

After having done this project I have a much better understanding of how Simscape works. The next project I will attempt to model on Simscape is an EV battery pack to some scale. I plan to include the thermal domain, which will be necessary for future modeling of the battery pack cooling system.

Appendix

Resources:

Simulink model & Script

CAD model

Gears

The driving/motor metal gear is pressed on to the motor shaft. The driven & layshaft gears will be made of laser cut Acetal/Delrin. This thermoplastic has good structural properties and superior bearing & wear properties (especially important in gears). Additionally, Acetal is much more dimensionally stable than Nylon making it a better candidate for laser cutting.

Below I carry out some calculations to validate these gears:

Fatigue Strength for 106 cycles (σ1) 36MPa
Service lifetime correction factor (Cn)0.22
Number of cycles in million (n)10(recommended)
Properties of Delrin 500

To calculate the nominal allowable fatigue stress we use the formula below:

\sigma_n=\sigma_1[1-C_n*log(n)] \space \space (\textrm{MPa})

To get σn=28.1MPa. To calculate the application specific allowable fatigue stress we must consider the velocity factor, Shock-load factor and the temperature factor using the formula below:

\sigma_{\textrm{app}}=\sigma_n*(1-0.6\frac{T-20}{80})*\frac{1}{1+\frac{\pi d\omega}{60000}}*c_{\textrm{sl}}

In this case the Shock load factor (csl) is 1 as there are no shock loads expected in this application. T is temperature which we will assume to be 25ºC as it far away from heat sources. d is the pitch diameter of the driven gear, which are 40mm respectively. ω is the rotational velocity at which the gear operates at, as seen from the graphs above it is on average (from the 0➙100% operation) ~400rpm.

Calculating the above we find the σapp=14.7MPa. This is representative of both gears as they are in the same system. The bending stress of the gear in our system can be found using the formula below:

\sigma_b=\frac{F}{yMf}

Where F is the max tangential force, which is equal to 11.8N. y is the tooth form factor, which in the case of the driven gear is 0.629 and 0.485 for the layshaft gear. M is the module, in this case 0.5 and f is the tooth width equal to 4mm. We find that the layshaft gear has a σbS=12.2MPa & the driven gear a σbB=9.38MPa.

We see that the bending stresses (σb) in our system are lower than the application specific fatigue stress (σapp), meaning that our gears are not expected to fail in their lifetime and so suitable for this application.

Motor Choice

The choice of a brushed dc motor seems appropriate in this application even though accurate position control is required. Compared to a stepper motor a dc motor offers much greater power density, which is something necessary to open the throttle fast whilst reducing weight. A brushless dc motor was not suitable as it would require an additional system outside the ECU to power and control the brushless motor, increasing overall complexity. Single phase brushless dc motors that can be driven off a standard h-bridge only exist in small continuous operation applications, like cooling fans.

When looking for a motor I created the following requirements:

  • The length of the body of the motor must be less than 40mm
  • Must be designed to run nominally at 12V
  • The extrapolated stall current must not exceed 6A, this is a requirement from the ECU.
RE-385 Motor

The above really narrowed down the choice of motors available. I came across the RE-385 dc motor, which met all of the requirements. Other options were also identified but these were smaller motors with lower stall currents, where the safety factor of burning them out was lower. Established manufacturers, like Maxon, also made motors meeting my requirements, however these were a factor of 100 more expensive than the chosen motor.

The RE-385 is a very common motor and is used on a variety of appliances and industrial actuation systems. It has a very low cost at £3.69 on RS components.

Advanced Headpose Estimation optimisation on a Raspberry Pi

The hardest portion of my latest project was the image recognition component. The challenge was to carry out Headpose Estimation on a Raspberry Pi at usable framerate. I will talk about why I chose the RPi 3 Model A+ as the SBC (Single Board Computer) and the changes I did to the base code to optimise it for the Raspberry Pi. 

Deciding the SBC

I first identified the SBC specifications that mattered most to the project. To carry out the image processing, I figured out that an SBC with the highest clock speed would work best and with multi-threading, given the nature of the process done it would only run on one processor core. Also, the program would be written in Python so for ease I wanted to run Linux so I needed an x86 or ARM processor. As for the RAM, the pattern recognition models I would be using are quite big in size and I couldn’t use smaller models because the images I would be processing were of low resolution so the models had to be robust. I clearly identified that I would need at least 512MB of RAM.

I also needed the SBC to have at least 1 set of UART pins and 1 set of I2C pins and a usb for the webcam.

I spent a number of evenings looking at all the market offering and yet again you end up choosing a Raspberry Pi as all the other offerings either don’t meet the required specs and show no documentation or are so expensive. I decided to use a Raspberry Pi 3 Model A+. Apart from being super cheap it offered a beefy processor and 512MB of RAM and the possibility of using the Camera Serial Interface (CSI).

Getting experience with Image Recognition

Before this project I had never done any image processing type programming. So I had no clue which libraries to use. I did a couple of simple tutorials from the amazing Python Programming , where I was introduced to the OpenCV library. This library is almost always used when it comes to working with images on Python, it can do everything from rotate images to apply some crazy filters. However, the processing I wanted to do was a bit more advanced than what these tutorials were teaching.

I discretised the problem and identified what I wanted from the code, which was to calculate the Euler angles between the face and the image plane, with this I would be able to see where the face was looking at. I then found out the technical name of my problem, Headpose Estimation. This is just an application of the commonly known Pose Estimation, which refers to the use of computers to estimate an objects orientation and position in an image domain. The process can be split into 2 main parts:

  1. Detection of the facial features, for example: eye pupils, ends of the lips… These features are given a corresponding 2D coordinate.
  2. Computing the Euler angles by creating and solving a Perspective-n-Point system with the data point of the facial features.

More specifically for my application the process would follow the steps below:

Figure 1

The Codebase I used

I came across this very cool GitHub that solved my problem quite effectively and I thought this would be the end of my problem. But after running it on my MacBook, I decided to run it on the RPi and got very poor performance. In my tests with positive face detection the system would take and average of 658ms to calculate one frame, in other words, it would process 1.5 frames per second (fps), versus the 19 fps my MacBook processes. This frame rate would be too low for smooth operation of the ErgoScreen as the users face can move a very considerable amount during this time interval.

Figure 2 (“wf” refers to test with positive face detection & “wof” refers to test with no face detection)

Exploring the results from the test with the base code (Figure 2) further. It is clear that the component of the process that takes the most time is the Bounding Box Estimation, it encompassed around 94% of the processing time. For those knowledgeable in the subject will understand that this is obvious as the system has to search the entire image and compare a larger amount of datapoints in order to establish the boundaries of the face. Knowing this I began to work on reducing the bounding box time.

Interestingly, from this data we can see the poor integration the FaceTime camera has on Mac’s where the image capture takes up to 35% of the processing time, compared to the Raspberry Pi. This is due to the fact that the FaceTime Camera is just a built in USB webcam.

Optimising the Bounding Box algorithm

The base code uses Dlib’s get_frontal_face_detector() function to calculate the bounding box. This function uses a Histogram of Oriented Gradients (HOG) algorithm which in theory is one of the most accurate methods for object recognition, however in this case we only need to consider faces which are looking strait towards the screen and this is where HOG is not as good as other algorithms.

HOG is mostly used in applications where object recognition is needed in a variety of environments and backgrounds, i.e. pedestrian detection. It works by detecting image details, like edges, and discarding the remaining background, these image details are segmented and analysed more closely in order to determine their gradient. The gradients are analysed collectively to determine if it’s the desired object.

Whilst this may sound perfect and efficient, it is very processing power intensive and has to be trained with a varied and complete dataset to work. In our case we are interested in discrete possibilities of where the object (face) resides so we don’t need all this processing. This is why simple algorithms like Haar cascade classifiers work much faster for my application. Haar classifiers convert the image to monochrome and compare the light and dark regions of the image to establish edges and shapes that belong to a face. This process is quick and very efficient and in this case, as accurate as HOG.

OpenCV has very well trained and optimised Haar classifiers models for faces. So I decided to try these out.

OpenCV’s detectMultiScale() function carries out the facial detection using a pre-defined CascadeClassifier class, which loads the desired model. This function has a very useful parameter, scaleFactor, which scales the image to simplify processing my looking for bigger objects, in this case faces, this speeds up processing time.

The output of the detectMultiScale() function is an array with the bottom left x,y coordinates of the bounding box and its width and height of every detected face. However, the function used to detect the facial landmarks, Dlib’s shape_predictor(), requires the bounding box to be defined by the bottom left x,y coordinates and the top right x,y coordinates. I was able to convert these by using Dlib’s rectangle() function.

Figure 3 (“wf” refers to test with positive face detection & “wof” refers to test with no face detection)

The effect of these changes can be seen on the Figure above. The processing using the Haar bounding box framework (“RPi_wmodel_wf & RPi_wmodel_wof”) take >70% less time than those with the HOG approach from Dlib and with almost no impact in accuracy. Moreover, with this change, the program achieved >5fps (Table 1) with the positive face detection test.

Optimising the Webcam Stream

Having seen and understood the results of Figure 3, the only possible remaining simple optimisation I could do would be modifying the image capture portion of the process. Even though the “Landmark” portion of the program encompasses the largest portion of the processing time after “Bounding Box”, optimising it would prove a great challenge as it is already very efficient and is only detecting a certain number of facial features. Similar to how “Bounding Box” works, “Landmarks”, which is a HOG based framework, must process the Bounding Box portion of the image for every chosen facial landmark and this will take time.

After “Landmarks”, “Image Capture” takes the most time and this is something that can be worked on.

The base code uses OpenCV’s standard approach for webcam streams, VideoCapture(), which will read frames from available webcams/cameras on the system. This function is very useful as it is universal and has many parameters and options but its method to retrieve images is relatively slow. It works by first creating a stream with the webcam, in other words it is informing the webcam to turn on and get ready to send frames. Then when we want a frame, we call VideoCapture.read(), this tells the webcam to take a frame and return it. Inherently, this takes a lot of time as we have to wait for the webcam to take and image and send it.

Considering I am using a RPi 3 Model A+, which has a quad-core processor, I can take advantage of this and use multi-threading to save time when retrieving the image frame. The imutils python package offers a very useful class, PiVideoStream, which in its self uses a process similar VideoCapture() but uses a separate thread to store the read images so when PiVideoStream.read() is called the last captured image is returned and there is no standby. Additionally, PiVideoStream uses a 320×240 resolution which is perfect for reducing the processing time of the later stages as a smaller number of pixels needs to be examined.

Figure 4 (“wf” refers to test with positive face detection & “wof” refers to test with no face detection)

Even though this change delivered less of an impact it is still visible in the results in Figure 4. “RPi_wmodel_cam_wf” resulted in a 5.81 fps, which is truly above the 5fps average. The “RPi_wmodel_cam_wof” test resulted in a 7.14fps, this is very good achievement as the system will be able to respond quicker when a new face is detected by the system.

It is evident that optimisation has led to better performance of this system. The optimisation delivered a 380% increase in fps in positive face tests on the RPi over the base code. Using the base code was very useful as it sped up the process and allowed me to focus on improving components rather than building them. Without this optimisation, my project would have dramatically increased in cost as I would have had to include a more powerful processing unit. This is a perfect example of where small adjustments in code can render greater performance whilst at a lower cost and time. Further work could have been done to decrease the “Landmarks” processing time by including it in the bounding box process, which in turn could be reduced even further by threading the processing of individual classifiers.

Appendix

The final code can be found here

Chevy Bolt Cooling Plates

Here are some Chiller Plates designed to fit Chevrolet Bolt battery modules. My neighbour is doing an EV conversion for his John Deere 4020 and he wanted to use Chevy Bolt modules because of their useful shape and amazing specific capacity. The OEM ones are from stamped aluminium and they aren’t that great so I designed some. We got 10 made for a price of less than $500 so they are quite cheap and they work really extremely well.

This design can easily be carried over to other battery designs specially as most upcoming EVs use pouch cells.

Complete

The number, size and fins will depend on your application. The number of fins you or even if you need fins depends mainly on the mass flow rate of the coolant and how you interface the cooling plate with the battery…

In our case we are using thermal pads between the battery and the cooling plate with a thickness of 0.5mm and a conductivity of 5W/(mK), which gives coefficient of heat transfer of 10kW/(m2K), this is more than double that of the coolant(water) flowing through our system which is ~4kW/(m2K). So in our case we do benefit from fins. However, if we were to just fasten them on to the battery we wouldn’t get any benefit from adding fins since the air gaps are the bottle neck.

I have added the CAD file below. Let me know if you have any doubts. Please acknowledge me if you plan to use it.

ErgoScreen: The intelligent monitor stand that will boost your productivity

This monitor stand uses advanced facial recognition technology and adjusts the orientation of your display to the position where it reduces eye strain the most. In the era of open workspaces where shared tools are used, it is more likely that a user will sit a display who’s orientation is not best suited for them. This device automates the process of adjusting the orientation of a monitor and will deliver a boost in productivity as eye strain is reduced.

Below is a short video of the device’s operation

It’s normal operation flow-chart can be seen below:

The system implements fault detection and isolation approaches and diagnostics similar to an OEM device. Different communication protocols are used for the motor controllers as their only IO options are I2C and Serial and the Raspberry Pi only has one I2C and one Serial driver.

The system allows quick implementation to the workplace and the webcam data from the Raspberry Pi can be routed out of the device through the USB so it can be used as a USB 10h slave device to a computer.

Below is a diagram of the components:

The construction of this device is experimental, the use of adhesives is vast. The current setup allows a lifting capacity of a 12Kg screen, which is more than the average ultra-wide screen. The image below captures the the materials constituting the structure:

The arm assembly for example is formed by bonded nylon sheets. This assembly can be seen below:

The Facial Recognition component of this project is quite advanced and was the hardest part of this project, so I will make a specific post about it and how I optimised it for use on the Raspberry Pi but here is a gif of what the system sees:

The device currently stands at a minimum viable product position, however I haven’t been able to build a prototype due to CovID-19 restrictions.

If you think it is a good idea and want to develop it further please contact me I would gladly help. I plan to modify the design so it operates more like an articulated robot so I can incorporate more degrees of freedom.