brake_sweep.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Software License Agreement (BSD License)
4 #
5 # Copyright (c) 2018, Dataspeed Inc.
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without modification,
9 # are permitted provided that the following conditions are met:
10 #
11 # * Redistributions of source code must retain the above copyright notice,
12 # this list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above copyright notice,
14 # this list of conditions and the following disclaimer in the documentation
15 # and/or other materials provided with the distribution.
16 # * Neither the name of Dataspeed Inc. nor the names of its
17 # contributors may be used to endorse or promote products derived from this
18 # software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 import rospy
32 import csv
33 from dbw_fca_msgs.msg import BrakeCmd, BrakeReport, BrakeInfoReport
34 from dbw_fca_msgs.msg import GearReport, SteeringReport
35 from math import fabs
36 
37 class BrakeSweep:
38  def __init__(self):
39  rospy.init_node('brake_sweep')
40 
41  # Variables for logging
42  self.brake_cmd = 0.0
43  self.msg_brake_report = BrakeReport()
45  self.msg_brake_info_report = BrakeInfoReport()
47 
48  # Other drive-by-wire variables
49  self.msg_gear_report = GearReport()
50  self.msg_gear_report_ready = False
51  self.msg_steering_report = SteeringReport()
53 
54  # Parameters
55  self.i = -1
56  self.start = 0.16
57  self.end = 0.50
58  self.resolution = 0.002
59  self.duration = rospy.Duration(0.5)
60  rospy.loginfo('Recording brake pedal data every ' + str(self.duration.to_sec()) + ' seconds from ' + str(self.start) + ' to ' + str(self.end) + ' with ' + str(self.resolution) + ' increments.')
61  rospy.loginfo('This will take ' + str((self.end - self.start) / self.resolution * self.duration.to_sec() / 60.0) + ' minutes.')
62 
63  # Open CSV file
64  self.csv_file = open('brake_sweep_data.csv', 'w')
65  self.csv_writer = csv.writer(self.csv_file, delimiter=',')
66  self.csv_writer.writerow(['Brake (%)', 'Measured (%)', 'Torque Request (Nm)', 'Torque Actual (Nm)', 'Pressure (bar)'])
67 
68  # Publishers and subscribers
69  self.pub = rospy.Publisher('/vehicle/brake_cmd', BrakeCmd, queue_size=1)
70  rospy.Subscriber('/vehicle/brake_report', BrakeReport, self.recv_brake)
71  rospy.Subscriber('/vehicle/brake_info_report', BrakeInfoReport, self.recv_brake_info)
72  rospy.Subscriber('/vehicle/gear_report', GearReport, self.recv_gear)
73  rospy.Subscriber('/vehicle/steering_report', SteeringReport, self.recv_steering)
74  rospy.Timer(rospy.Duration(0.02), self.timer_cmd)
75  rospy.Timer(self.duration, self.timer_process)
76 
77  def timer_process(self, event):
78  if self.i < 0:
79  # Check for safe conditions
80  if not self.msg_steering_report_ready:
81  rospy.logerr('Speed check failed. No messages on topic \'/vehicle/steering_report\'')
82  rospy.signal_shutdown('')
83  if self.msg_steering_report.speed > 1.0:
84  rospy.logerr('Speed check failed. Vehicle speed is greater than 1 m/s.')
85  rospy.signal_shutdown('')
86  if not self.msg_gear_report_ready:
87  rospy.logerr('Gear check failed. No messages on topic \'/vehicle/gear_report\'')
88  rospy.signal_shutdown('')
89  #if not self.msg_gear_report.state.gear == self.msg_gear_report.state.PARK:
90  # rospy.logerr('Gear check failed. Vehicle not in park.')
91  # rospy.signal_shutdown('')
92  elif self.i < int((self.end - self.start) / self.resolution + 1):
93  # Check for new messages
94  if not self.msg_brake_report_ready:
95  rospy.logerr('No new messages on topic \'/vehicle/brake_report\'')
96  rospy.signal_shutdown('')
97  if not self.msg_brake_info_report_ready:
98  rospy.logerr('No new messages on topic \'/vehicle/brake_info_report\'')
99  rospy.signal_shutdown('')
100  if not self.msg_brake_report.enabled:
101  rospy.logerr('Brake module not enabled!')
102  rospy.signal_shutdown('')
103  #if self.msg_brake_report.pedal_input > 0.19:
104  # rospy.logwarn('Take your foot off the brake pedal! This will corrupt the measurement.')
105 
106  # Make sure values are close to expected
107  diff = self.brake_cmd - self.msg_brake_report.pedal_output
108  if (fabs(diff) > 0.01):
109  rospy.logwarn('Not saving data point. Large disparity between pedal request and actual: ' + str(diff))
110  else:
111  # Write data to file
112  rospy.loginfo('Data point: ' + "{:.03f}".format(self.msg_brake_report.pedal_output) + ', ' +
113  "{:.01f}".format(self.msg_brake_info_report.brake_pc) + ', ' +
114  "{:.01f}".format(self.msg_brake_info_report.brake_torque_request) + ', ' +
115  "{:.01f}".format(self.msg_brake_info_report.brake_torque_actual) + ', ' +
116  "{:.01f}".format(self.msg_brake_info_report.brake_pressure))
117  self.csv_writer.writerow(["{:.03f}".format(self.msg_brake_report.pedal_output),
118  "{:.01f}".format(self.msg_brake_info_report.brake_pc),
119  "{:.01f}".format(self.msg_brake_info_report.brake_torque_request),
120  "{:.01f}".format(self.msg_brake_info_report.brake_torque_actual),
121  "{:.01f}".format(self.msg_brake_info_report.brake_pressure)])
122  else:
123  rospy.signal_shutdown('')
124 
125  # Prepare for next iteration
126  self.i += 1
127  self.msg_brake_report_ready = False
128  self.msg_brake_info_report_ready = False
129  self.brake_cmd = self.start + self.i * self.resolution
130 
131  def timer_cmd(self, event):
132  if self.brake_cmd > 0:
133  msg = BrakeCmd()
134  msg.enable = True
135  msg.pedal_cmd_type = BrakeCmd.CMD_PEDAL
136  msg.pedal_cmd = self.brake_cmd
137  self.pub.publish(msg)
138 
139  def recv_brake(self, msg):
140  self.msg_brake_report = msg
141  self.msg_brake_report_ready = True
142 
143  def recv_brake_info(self, msg):
144  self.msg_brake_info_report = msg
145  self.msg_brake_info_report_ready = True
146 
147  def recv_gear(self, msg):
148  self.msg_gear_report = msg
149  self.msg_gear_report_ready = True
150 
151  def recv_steering(self, msg):
152  self.msg_steering_report = msg
153  self.msg_steering_report_ready = True
154 
155  def shutdown_handler(self):
156  rospy.loginfo('Saving csv file')
157  self.csv_file.close()
158 
159 if __name__ == '__main__':
160  try:
161  node = BrakeSweep()
162  rospy.on_shutdown(node.shutdown_handler)
163  rospy.spin()
164  except rospy.ROSInterruptException:
165  pass
def recv_brake(self, msg)
Definition: brake_sweep.py:139
def recv_brake_info(self, msg)
Definition: brake_sweep.py:143
def recv_steering(self, msg)
Definition: brake_sweep.py:151
def shutdown_handler(self)
Definition: brake_sweep.py:155
def timer_process(self, event)
Definition: brake_sweep.py:77
def recv_gear(self, msg)
Definition: brake_sweep.py:147
def timer_cmd(self, event)
Definition: brake_sweep.py:131


dbw_fca_can
Author(s): Kevin Hallenbeck
autogenerated on Wed May 12 2021 02:14:05