The timer used here doesn't have a t=0 set time. How does it know when to start? Sorry if this is a silly question.
public partial class Form1 : Form
{
double t;
double dt = 0.1;
StreamWriter myfile = new StreamWriter("myresults.csv");
double previous_error = 0;
double integral = 0;
double error;
double setpoint = 0;
double measured_value;
double derivative;
double output;
double SpeedAccuracy = 0;
double Kp = 0.05, Ki = 0, Kd = 0;
double k1 = -2, k2 = 2;
private void timer1_Tick(object sender, EventArgs e)
{
if (car.speedX == 0) return;
*CODE BODY*
t = t + dt
Thanks in advance.
Nick
2 Replies
Know the answer? Post it — somebody with the same question will find it here.
Sign in to answer this question
It is the same account you read, post and publish with — and you will come straight back to this page.
Nick GoodsonPosted May 22, 2016, 12:41 PM
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using torcs;
using System.Windows.Forms.DataVisualization.Charting;
}
namespace unmannedCar
{
public partial class Form1 : Form
{
double t;
double dt = 0.1;
StreamWriter myfile = new StreamWriter("myresults.csv");
double previous_error = 0;
double integral = 0;
double error;
double setpoint = 0;
double measured_value;
double derivative;
double output;
double SpeedAccuracy = 0;
double Kp = 0.05, Ki = 0, Kd = 0;
double k1 = -2, k2 = 2;
private void timer1_Tick(object sender, EventArgs e)
{
if (car.speedX == 0) return;
measured_value = car.speedX;
error = setpoint - measured_value;
integral = integral + error * dt;
derivative = (error - previous_error) / dt;
output = Kp * error + Ki * integral + Kd * derivative;
if (output > 1)
output = 1;
if (output < 0)
output = 0;
previous_error = error;
setpoint = car.track[9] * 1.2;
SpeedAccuracy = 0.9999 * SpeedAccuracy + 0.0001 * error;
if (error > 0)
{
car.accel = output;
car.brake = 0;
}
else if (error < 0)
{
car.accel = 0;
car.brake = -output;
}
// turn the steering wheel
car.steer = k1 * car.trackPos + k2 * car.angle;
// Gear Change Up
if (car.rpm>=5000 & car.gear <6)
{
car.gear = car.gear + 1;
}
// Gear Change Down
if (car.rpm<=3600 & car.gear>1)
{
car.gear = car.gear - 1;
}
// send the new controls to the car
car.sendcontrols();
// display some results on screen
label1.Text = car.speedX.ToString("0000.00");
label2.Text = car.accel.ToString("0.0000");
label3.Text = t.ToString("##0.0");
label4.Text = car.track[9].ToString("##0.0");
label5.Text = output.ToString("0000.00");
label6.Text = SpeedAccuracy.ToString("0.000");
label9.Text = car.distFromStart.ToString("0.0");
label11.Text = setpoint.ToString("0.00");
// save some results to a file so you can analyse them later in Excel
myfile.WriteLine(t.ToString("000.0") + "," +
setpoint.ToString("0") + "," +
car.accel.ToString("0.00") + "," +
car.rpm.ToString("0000") + "," +
car.lastLapTime.ToString("0000")
);
myfile.Flush();
// plot the next points on the chart
chart1.Series["speedX"].Points.AddXY(t, car.speedX);
chart1.Series["accel"].Points.AddXY(t, car.accel * 5000);
chart1.Series["setpoint"].Points.AddXY(t, setpoint);
chart2.Series["trackpos"].Points.AddXY(t, car.trackPos); // update the timer
t = t + dt;
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// setup the chart axes
chart1.Series[0].ChartType = SeriesChartType.Line;
chart1.Series[0].Name = "speedX";
chart1.Series.Add("accel");
chart1.Series.Add("setpoint");
chart1.Series[1].ChartType = SeriesChartType.Line;
chart1.Series[2].ChartType = SeriesChartType.Line;
chart1.ChartAreas[0].AxisX.Minimum = 0;
chart1.ChartAreas[0].AxisX.Maximum = 20;
chart1.ChartAreas[0].AxisX.Interval = 5;
chart1.ChartAreas[0].AxisX.Title = "secs";
chart1.ChartAreas[0].AxisY.Minimum = 0;
chart1.ChartAreas[0].AxisY.Maximum = 100;
chart1.ChartAreas[0].AxisY.Interval = 10;
chart1.Titles.Add("stepresponse");
chart2.Series[0].ChartType = SeriesChartType.Line;
chart2.Series[0].Name = "trackpos";
chart2.ChartAreas[0].AxisX.Minimum = 0;
chart2.ChartAreas[0].AxisX.Maximum = 20;
chart2.ChartAreas[0].AxisX.Interval = 5;
chart2.ChartAreas[0].AxisX.Title = "secs";
chart2.ChartAreas[0].AxisY.Minimum = -1;
chart2.ChartAreas[0].AxisY.Maximum = 1;
chart2.ChartAreas[0].AxisY.Interval = 0.1;
chart2.Titles.Add("stepresponse2");
// connects to the Car
comms.setupConnection(this);
// sets the loop time to 1000 milliseconds
timer1.Interval = (int)(dt * 1000);
timer1.Enabled = true;
t = 0;
myfile.WriteLine("t, setpoint, accel, rpm, Lap Time");
}
private void button1_Click(object sender, EventArgs e)
{
k1 = Convert.ToDouble(textBox1.Text);
}
private void label4_Click(object sender, EventArgs e)
{
}
}
Ibrahim ErsoyPosted May 22, 2016, 11:48 AM
You need to set Timer's Enabled property to True to start timer1_Tick function.
You can stop or start as long as you set its Enabled property to true or false.