Hello Urara, 

Sorry for missing that the code was still not behaving as expected. 

Could you try this piece of code


     wheel = self.my_hmmwv.GetVehicle().GetWheel(0, 0).GetSpindle()

     wheel_normal_abs = wheel.GetA().Get_A_Yaxis()

     wheel_normal_loc = self.my_hmmwv.GetChassisBody(

     ).TransformDirectionParentToLocal(wheel_normal_abs)

     wheel_angle = np.arctan2(

         wheel_normal_loc.y, wheel_normal_loc.x) - np.pi/2

     toe_in = wheel_angle

It seems to be giving the right plot for the left front tire. Its the same 
idea as before, except now we compute the angle with respect to the chassis 
body's heading. Attached is the plot I get. Also its better if we don't 
refer this angle as the "toe" angle because the "toe" angle is usually 
defined at 0 steer and is a static parameter. 

Let me know if this looks okay
On Thursday, November 9, 2023 at 2:32:45 PM UTC-6 [email protected] 
wrote:

> 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/3748c7d8-9f8b-4fad-809a-0d37141a5608n%40googlegroups.com.

Reply via email to