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) 2014-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_mkz_msgs.msg import BrakeCmd, BrakeReport, BrakeInfoReport
34 from dbw_mkz_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.15
57  self.end = 0.35
58  self.resolution = 0.001
59  self.duration = rospy.Duration(3.0)
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 (%)', 'Torque Request (Nm)', 'Torque Actual (Nm)'])
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  str(self.msg_brake_info_report.brake_torque_request) + ', ' +
114  str(self.msg_brake_info_report.brake_torque_actual))
115  self.csv_writer.writerow(["{:.03f}".format(self.msg_brake_report.pedal_output),
116  "{:.01f}".format(self.msg_brake_info_report.brake_torque_request),
117  "{:.01f}".format(self.msg_brake_info_report.brake_torque_actual)])
118  else:
119  rospy.signal_shutdown('')
120 
121  # Prepare for next iteration
122  self.i += 1
123  self.msg_brake_report_ready = False
124  self.msg_brake_info_report_ready = False
125  self.brake_cmd = self.start + self.i * self.resolution
126 
127  def timer_cmd(self, event):
128  if self.brake_cmd > 0:
129  msg = BrakeCmd()
130  msg.enable = True
131  msg.pedal_cmd_type = BrakeCmd.CMD_PEDAL
132  msg.pedal_cmd = self.brake_cmd
133  if msg.pedal_cmd > 0.2:
134  msg.boo_cmd = True
135  self.pub.publish(msg)
136 
137  def recv_brake(self, msg):
138  self.msg_brake_report = msg
139  self.msg_brake_report_ready = True
140 
141  def recv_brake_info(self, msg):
142  self.msg_brake_info_report = msg
143  self.msg_brake_info_report_ready = True
144 
145  def recv_gear(self, msg):
146  self.msg_gear_report = msg
147  self.msg_gear_report_ready = True
148 
149  def recv_steering(self, msg):
150  self.msg_steering_report = msg
151  self.msg_steering_report_ready = True
152 
153  def shutdown_handler(self):
154  rospy.loginfo('Saving csv file')
155  self.csv_file.close()
156 
157 if __name__ == '__main__':
158  try:
159  node = BrakeSweep()
160  rospy.on_shutdown(node.shutdown_handler)
161  rospy.spin()
162  except rospy.ROSInterruptException:
163  pass
def recv_brake(self, msg)
Definition: brake_sweep.py:137
def recv_brake_info(self, msg)
Definition: brake_sweep.py:141
def recv_steering(self, msg)
Definition: brake_sweep.py:149
def shutdown_handler(self)
Definition: brake_sweep.py:153
def timer_process(self, event)
Definition: brake_sweep.py:77
def recv_gear(self, msg)
Definition: brake_sweep.py:145
def timer_cmd(self, event)
Definition: brake_sweep.py:127


dbw_mkz_can
Author(s): Kevin Hallenbeck
autogenerated on Fri May 14 2021 02:47:08