Frequency Response of Unknown System from Freq Chirp and FFT's
-------------

My understanding from further discussion with the OP that he wants to specifically use an approach of providing a swept sine wave stimulus and use the FFT of this input and system output response to derive the transfer function. This may be for a system identification problem where the swept tone will provide more power per frequency bin than a direct impulse response can provide, so would be more practical for experimental test purposes. This would be an alternative approach for comparison to traditional channel estimation approaches using noise-like stimulus (PN codes) and least squares estimation techniques such as those described here: https://dsp.stackexchange.com/questions/31318/compensating-loudspeaker-frequency-response-in-an-audio-signal

That said this approach should work well with certain considerations that I will outline below:

**Frequency Ramp Generation** This post and specifically the derivation from @MattL is a useful reference on setting the start frequency and stop frequency within a FM chirp (frequency ramp) signal to create the desired instantaneous frequencies accurately.

https://dsp.stackexchange.com/questions/31578/simulation-of-a-frequency-ramp

Here he provided the solution copied below for the values of $f(t)$ in the chirp  function $\cos\big(2\pi f(t) t\big)$ such that the instantaneous frequency will start at $F_1$ at time $t_1$ and end at $F_2$ at time $t_2$

$$\begin{align}f(t)&=F_1-\frac{\Delta F}{\Delta t}t_1+\frac12\frac{\Delta F}{\Delta t}t,\quad t_1<t<t_2\tag{1}\end{align}\\$$ with $\Delta F=F_2-F_1$ and $\Delta t=t_2-t_1$.



**Windowing** Windowing will be important to minimize distortion in the DFT results. However given we are sweeping the input frequency with time, tapering the signal at the boundaries will reduce the signal levels at these test frequencies. An excellent window choice for this application is the Tukey window as we can selectively taper just the outer edges, while the majority of the window is flat, offering significant performance in frequency even with a relatively small $\alpha$ which is the ratio of the taper portion of the window to the flat portion.  Additionally with a low $\alpha$ the resolution bandwidth is minimally impacted.

**Sampling Rate** Given the application will be to use a real tone, the sampling rate needs to be higher than twice the highest frequency over which we would like to measure the transfer function.   

**Number of Samples** The number of samples is set based on the resolution bandwidth desired for the transfer function measurement. The number of samples will set the total time duration $T$ of the test signal, which will set the resolution bandwidth of the test according to $1/T$ (as mentioned above, the Tukey window if low $\alpha$ is used will not significantly impact the resolution bandwidth.)  

**Transfer Function** With the above considerations, the transfer function is derived by the ratio of the output FFT to the input FFT. This would be a complex function with its associated magnitude and phase components.

Demonstration
-------------

This was done using the same transfer function as the OP used in his own answer for comparison given as:

$$G(s) = \frac{3}{s^2 + 0.5s +30}$$

In application the transfer function is the unknown, and the objective is to determine the frequency response of this unknown transfer function, and specifically in this case using a real sinusoidal frequency ramp stimulus and FFT's. So this transfer function was used to generate the actual output which was then used along with only the input to predict the frequency response.  

Below is the resulting estimated frequency response versus ideal showing excellent agreement between the two:

[![Freq Response][1]][1]

Here is the MATLAB/Octave code for the optimized sinusoidal (real) ramp for FFT processing. This generates a cosine frequency chirp with Tukey amplitude taper at the start and end of the chip, along with constant frequency in the taper for optimized FFT performance for use with determining a transfer function. 

    function out = chirp(N, r = 0.05, w1=0, w2=pi);
      # Dan Boschen 4/18/2020
      
      n= 0:N-1;                       # sample index
      n1 = ceil(r*N/4);               # start ramp at 50% in window rise 
      n2 = N-n1-1;                    # end ramp at 50% in window fall
    
      # phase versus time for linear ramp 
      psweep = w1*n + (w2-w1)/(n2-n1)*((n.^2+n1^2)/2-n1*n);
    
      # constant frequency outside of Tukey window
      psweep(1:n1) = w1*n(1:n1);
      psweep(n2:end) = psweep(n2)+w2*n(n2:end)-w2*n(n2);
    
      win = tukeywin(N, r)';        # Tukey Window
      out = win.*cos(psweep);        
      
    end


The following script demonstrates proper use of the chirp:

    N = 4096;             # number of samples
    fs = 60;              # sampling rate 
    n = 0:N-1;            # sample index
    t = n/fs;             # time index
    
    # frequency chirp stimulus
    u = chirp(N, r = 0.05, w1=0, w2=pi);  
    
    G = tf([3], [1 0.5 30]);    # OP's trasfer function
    y = lsim(G, u, t)';         # Generate output as OP has done
    fu = fft(u);        
    fy = fft(y);
    resp = fy./fu;              # derived frequency response
    
    # plot
    figure;
    faxis = n/N*fs;
    half = floor(N/2);
    semilogx(2*pi*faxis(1:half), 20*log10(abs(resp(1:half))));


The reason this works so well is due to the excellent flatness in the DFT of the chirp signal through careful planning in generating such a signal for use in the DFT.  Following the considerations listed above, the chirp stimulus has the following characteristics versus frequency and time. The taper duration is greatly exagerated in this diagram below; a 5% ratio was actually used for the demonstration above.  Importantly at no time during the chirp does the frequency repeat; given the requirement for a real signal, any repetition of a frequency later in time would result in deep nulls in the response. Going below $0$ or above $\pi$ would essentially create such a repetition, therefore the frequency was made to be constant at the edges while allowing the ramp to extend fully from $0$ to $\pi$ in normalized radian frequency (cylces/sample). Sidelobe ringing was minimized by extending the ramp 50% into the taper of the amplitude window. 

[![Chirp Preparation][2]][2]

An FFT of the chirp signal itself shows these performance features including complete frequency coverage and overall flatness approaching that of an ideal impulse (while allowing for much larger overall signal power thus we would expect much better performance versus an impulse response test in the presence of noise.)

[![FFT of chirp][3]][3]
 


  [1]: https://i.sstatic.net/t4a0G.png
  [2]: https://i.sstatic.net/Dzhqp.png
  [3]: https://i.sstatic.net/CTNCl.png