Hello,
Posting a question on a related topic here - about retrieving vehicle
states.
I have been able to extract speed, positions, rotations etc. from chrono
using some of the GetX() functions as below:
auto marker_com =
hmmwv.GetChassis()->GetMarkers()[1]->GetAbsCoord().pos;
double current_spd = hmmwv.GetVehicle().GetSpeed();
//ChQuaternion current_quat = hmmwv.GetVehicle().GetRot();
//ChVector current_rot = current_quat.Q_to_Euler123();
double current_yaw =
hmmwv.GetVehicle().GetRot().Q_to_Euler123().z(); //radians
I have not yet come across an existing function that retrieves the current
Yaw Rate (rad/sec) of the vehicle directly. Is there such a function
already that I can utilize? Or is there an attribute that I can access for
this?
Thanks!
Prakhar Gupta
PhD Student
Clemson University
On Monday 13 November 2023 at 14:31:52 UTC-5 [email protected] wrote:
> 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/10a6bc2f-5519-4a21-b4e3-ab79932c2765n%40googlegroups.com.