Dear Huzaifa, Thank you for checking my codes!
I corrected my codes, but now all my four wheels stay 0. In the plot you sent me, it also seems that all four wheels are 0 and only the driver input is 30 degrees. My code currently sets all wheel drive in init_vehicle() in chrono_env/utils.py. So shouldn't all four wheels be 0 at the beginning and go up to 30 degrees? I attached the plot that only plots the front left wheel and driver's input. '1st_code.png' and '2nd_code.png' correspond to the two patterns of your suggested codes. I additionally tried two other methods in step() in chrono_env.py. However, none of these gave the results that I expected. I calculated the Euler angle of the wheel with respect to the vehicle (chassis) frame. They should give roll and pitch being always 0 and yaw being 30 degrees. I pushed this code and the figures to the same repo again. https://github.com/UraraKono/pychrono-steering Would you mind taking a look at my code again? Best regards, Urara On Thu, Nov 9, 2023 at 9:59 AM 'HUZAIFA MUSTAFA UNJHAWALA' via ProjectChrono <[email protected]> wrote: > Hello Urara, > > I made a mistake in my code above. Changing your toe-in function from > > def get_toe_in(self, wheel_state_global): > # Wheel normal expressed in global frame > wheel_normal = wheel_state_global.rot.GetYaxis() > # Terrain normal at wheel location expressed in global frame > Z_dir = self.terrain.GetNormal(wheel_state_global.pos) > # Longitudinal (heading) and lateral directions, in the terrain plane > wheel_normal_np = np.array([wheel_normal.x, wheel_normal.y, > wheel_normal.z]) > > #Vcross cannot be found in pychrono. So I'm converting ChVectorD to > numpy array and using np.cross > Z_dir_np = np.array([Z_dir.x, Z_dir.y, Z_dir.z]) > X_dir_np = np.cross(wheel_normal_np, Z_dir_np) > X_dir = chrono.ChVectorD(X_dir_np[0], X_dir_np[1], X_dir_np[2]) > X_dir.Normalize() > X_dir_np = np.array([X_dir.x, X_dir.y, X_dir.z]) > Y_dir_np = np.cross(Z_dir_np, X_dir_np) > Y_dir = chrono.ChVectorD(Y_dir_np[0], Y_dir_np[1], Y_dir_np[2]) > rot = chrono.ChMatrix33D() > rot.Set_A_axis(X_dir, Y_dir, Z_dir) > tire_csys = chrono.ChCoordsysD(wheel_state_global.pos, > rot.Get_A_quaternion()) > > # Express wheel normal in tire frame > n = tire_csys.TransformDirectionParentToLocal(wheel_normal) > # print("n",n.x, n.y, n.z) > > # Wheel normal in the vehicle frame > n_v = > self.my_hmmwv.GetVehicle().GetTransform().TransformDirectionLocalToParent(wheel_normal) > > # Toe-in > toe_in = math.atan2(n_v.x, n_v.y) > > return toe_in > > To > > def get_toe_in(self, wheel_state_global): > # Wheel normal expressed in global frame > wheel_normal = wheel_state_global.rot.GetYaxis() > # Terrain normal at wheel location expressed in global frame > Z_dir = self.terrain.GetNormal(wheel_state_global.pos) > # Longitudinal (heading) and lateral directions, in the terrain plane > wheel_normal_np = np.array([wheel_normal.x, wheel_normal.y, > wheel_normal.z]) > > #Vcross cannot be found in pychrono. So I'm converting ChVectorD to numpy > array and using np.cross > Z_dir_np = np.array([Z_dir.x, Z_dir.y, Z_dir.z]) > X_dir_np = np.cross(wheel_normal_np, Z_dir_np) > X_dir = chrono.ChVectorD(X_dir_np[0], X_dir_np[1], X_dir_np[2]) > X_dir.Normalize() > X_dir_np = np.array([X_dir.x, X_dir.y, X_dir.z]) > Y_dir_np = np.cross(Z_dir_np, X_dir_np) > Y_dir = chrono.ChVectorD(Y_dir_np[0], Y_dir_np[1], Y_dir_np[2]) > rot = chrono.ChMatrix33D() > rot.Set_A_axis(X_dir, Y_dir, Z_dir) > tire_csys = chrono.ChCoordsysD(wheel_state_global.pos, > rot.Get_A_quaternion()) > > # Express wheel normal in tire frame > n = tire_csys.TransformDirectionParentToLocal(wheel_normal) > # print("n",n.x, n.y, n.z) > > # Toe-in > toe_in = math.atan2(n.x, n.y) > > return toe_in > > The mistake is that the code unnecessarily converted the wheel normal back > to the vehicle frame and used that for the toe-in computation. So as you > rightly pointed out, the angles were in vehicle frame. > > That being said, I realized that the approach I proposed is too > convoluted, the following code also works > > # Get wheel state > wheel_state_global = self.my_hmmwv.GetVehicle().GetWheel(0,0).GetState() #in > global frame > # Express wheel normal in tire frame > wheel_normal = wheel_state_global.rot.GetYaxis() > n = self.my_hmmwv.GetVehicle().GetWheel(0,0 > ).GetTransform().TransformDirectionParentToLocal(wheel_normal) > # toe_in = get_toe_in(self, wheel_state_global) > toe_in = math.atan2(n.x, n.y) > > This directly gets the tire frame using GetTransform(). > These modified functions produce the following plot, which I think is what > we expect > > Best Huzaifa > > On Wednesday, November 8, 2023 at 11:02:54 AM UTC-6 [email protected] > wrote: > >> Dear Huzaifa, >> >> Thank you so much! This is the link to my code: >> https://github.com/UraraKono/pychrono-steering >> <https://urldefense.com/v3/__https://github.com/UraraKono/pychrono-steering__;!!IBzWLUs!VjMQTjj7XYOajqdEp2lng6LR8VoirumLVvQh9bxVJkIHsL9lfVWBopcU5pDozX8ZAUT0sVo0oEycxoQ5TyAhcEl1btSDG3s$> >> Could you first look at the README file to get the overview of my code? >> Please run main.py. >> >> Best regards, >> Urara >> >> On Mon, Nov 6, 2023 at 1:02 PM 'HUZAIFA MUSTAFA UNJHAWALA' via >> ProjectChrono <[email protected]> wrote: >> >>> Hello Urara, >>> >>> The code I provided for toe_in_r is what I suppose is the \delta from >>> your image. However note that the vehicles in PyChrono are 4 wheeled, so >>> you might need to make an approximation to get the \delta from the image >>> (maybe take the average). >>> That being said, from your plot, it is surprising that the rear tires >>> have a toe angle and the angle keeps decreasing. Can you please post here >>> the snippet of code that generated the data for the plots? I can try taking >>> a quick look and reproduce this on my end. >>> >>> Best >>> Huzaifa >>> >>> On Friday, November 3, 2023 at 11:03:56 AM UTC-5 [email protected] >>> wrote: >>> >>>> Hello, >>>> >>>> Thank you so much for the reply! >>>> By "steering velocity and acceleration", I meant the steering angular >>>> velocity of the tires and the longitudinal acceleration of the vehicle >>>> body. >>>> >>>> I tried your code in Pychrono. >>>> However, even though I set the driver's steering input to be always "1" >>>> so that the vehicle keeps turning anti-clock-wise, the toe_in_r of all four >>>> wheels kept decreasing as shown in "toe-in.png". >>>> The trajectory is shown in "trajectory.png". The vehicle starts from >>>> (0,0) and keeps turning to the left. >>>> Maybe the toe-in obtained from your code is still in the global frame? >>>> >>>> Is toe_in_r equivalent to "δ" in the screenshot of the vehicle model >>>> figure attached to this email? >>>> I want to obtain this "δ". >>>> >>>> Best regards, >>>> Urara >>>> >>>> >>>> >>>> >>>> On Wednesday, November 1, 2023 at 9:55:12 AM UTC-4 [email protected] >>>> wrote: >>>> >>>>> Hello, >>>>> >>>>> Do you want to get the angle by which the tire-wheel steers? >>>>> GetSteering will only give you the normalized steering input (between -1 >>>>> and 1) that the driver applies onto the steering wheel at the current time >>>>> step. >>>>> If you would like to get the tire-wheel steer angle, you could do >>>>> something like this >>>>> >>>>> // Get the right wheel state >>>>> auto state = vehicle.GetWheel(0, >>>>> VehicleSide{RIGHT})->GetState(); >>>>> // Wheel normal (expressed in global frame) >>>>> ChVector<> wheel_normal = state.rot.GetYaxis(); >>>>> >>>>> // Terrain normal at wheel location (expressed in global >>>>> frame) >>>>> ChVector<> Z_dir = terrain.GetNormal(state.pos); >>>>> >>>>> // Longitudinal (heading) and lateral directions, in the >>>>> terrain plane >>>>> ChVector<> X_dir = Vcross(wheel_normal, Z_dir); >>>>> X_dir.Normalize(); >>>>> ChVector<> Y_dir = Vcross(Z_dir, X_dir); >>>>> >>>>> // Tire reference coordinate system >>>>> ChMatrix33<> rot; >>>>> rot.Set_A_axis(X_dir, Y_dir, Z_dir); >>>>> ChCoordsys<> tire_csys(state.pos, rot.Get_A_quaternion()); >>>>> >>>>> // Express wheel normal in tire frame >>>>> ChVector<> n = >>>>> tire_csys.TransformDirectionParentToLocal(wheel_normal); >>>>> >>>>> // Wheel normal in the Vehicle frame >>>>> ChVector<> n_v = >>>>> vehicle.GetTransform().TransformDirectionParentToLocal(wheel_normal); >>>>> >>>>> // Toe-in >>>>> auto toe_in_r = std::atan2(n_v.x(), n_v.y()); >>>>> >>>>> However, I do not understand what you mean by "steering velocity and >>>>> acceleration", do you want to control the lateral velocity and >>>>> acceleration >>>>> of the vehicle? >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> On Monday, October 23, 2023 at 9:23:40 AM UTC-5 [email protected] >>>>> wrote: >>>>> >>>>>> Hello, >>>>>> >>>>>> Thank you so much for providing this wonderful simulator. >>>>>> I'm new to Pychrono and I have a question. >>>>>> >>>>>> I'm trying to modify demo_VEH_SteeringController.py so that the >>>>>> vehicle can accept steering velocity and acceleration commands. I want to >>>>>> convert these two commands into throttle, brake, and steering input. >>>>>> ChPathFillowerDriver has GetSteering to get the driver steering >>>>>> *input,* but how can I get the *current actual *steering angle so >>>>>> that I can implement a PID controller for the steering? >>>>>> >>>>>> Or in this simulation, is it assumed that the driver steering input >>>>>> is always the same as the actual steering? >>>>>> >>>>>> Best regards, >>>>>> Urara >>>>>> >>>>> -- >>> You received this message because you are subscribed to a topic in the >>> Google Groups "ProjectChrono" group. >>> To unsubscribe from this topic, visit >>> https://groups.google.com/d/topic/projectchrono/bGrK7NFxsBI/unsubscribe >>> <https://urldefense.com/v3/__https://groups.google.com/d/topic/projectchrono/bGrK7NFxsBI/unsubscribe__;!!IBzWLUs!VEreeTZm1KgpDeiWYmCTDRYWhiKJqfzXDEKYU59kbFDJ_2ZcUm7gnZiztNrlSdmlWbNvWiYj1gv6pD9ZozBOiFn11u021xw$> >>> . >>> To unsubscribe from this group and all its topics, send an email to >>> [email protected]. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/projectchrono/235b7608-63bb-46a4-91e0-0f27f75e0e06n%40googlegroups.com >>> <https://urldefense.com/v3/__https://groups.google.com/d/msgid/projectchrono/235b7608-63bb-46a4-91e0-0f27f75e0e06n*40googlegroups.com?utm_medium=email&utm_source=footer__;JQ!!IBzWLUs!VEreeTZm1KgpDeiWYmCTDRYWhiKJqfzXDEKYU59kbFDJ_2ZcUm7gnZiztNrlSdmlWbNvWiYj1gv6pD9ZozBOiFn1bxQTjlE$> >>> . >>> >> >> >> -- >> *Urara Kono*, Ph.D. student >> GRASP Laboratory <https://www.grasp.upenn.edu> >> Electrical and Systems Engineering >> University of Pennsylvania >> she/her/hers >> > -- > You received this message because you are subscribed to a topic in the > Google Groups "ProjectChrono" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/projectchrono/bGrK7NFxsBI/unsubscribe > <https://urldefense.com/v3/__https://groups.google.com/d/topic/projectchrono/bGrK7NFxsBI/unsubscribe__;!!IBzWLUs!VjMQTjj7XYOajqdEp2lng6LR8VoirumLVvQh9bxVJkIHsL9lfVWBopcU5pDozX8ZAUT0sVo0oEycxoQ5TyAhcEl1qA0Ruoc$> > . > To unsubscribe from this group and all its topics, send an email to > [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/projectchrono/1730ba00-7e2a-43eb-b546-e82ce77b3293n%40googlegroups.com > <https://urldefense.com/v3/__https://groups.google.com/d/msgid/projectchrono/1730ba00-7e2a-43eb-b546-e82ce77b3293n*40googlegroups.com?utm_medium=email&utm_source=footer__;JQ!!IBzWLUs!VjMQTjj7XYOajqdEp2lng6LR8VoirumLVvQh9bxVJkIHsL9lfVWBopcU5pDozX8ZAUT0sVo0oEycxoQ5TyAhcEl1KkAg4tw$> > . > -- *Urara Kono*, Ph.D. student GRASP Laboratory <https://www.grasp.upenn.edu> Electrical and Systems Engineering University of Pennsylvania she/her/hers -- You received this message because you are subscribed to the Google Groups "ProjectChrono" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/projectchrono/CALLEzkOQUVcVYWdbPY4jx44C8aaq2fjxzTYDBcYzY729MyodNQ%40mail.gmail.com.
